Использование регулярных выражений для сопоставления URL-адреса для функции маршрута.Не могу заставить Regex работать - PullRequest
0 голосов
/ 16 декабря 2011

Я пытаюсь построить функцию маршрутизатора, чтобы правильно сопоставлять входящие URI и сопоставлять их с массивом хранимых системных URI.У меня также есть символы подстановки '(: any)' и '(: num)', похожие на CodeIgniter.

По сути, я пытаюсь получить запись «admin / stats / (: num)» для соответствия как «admin / stats», так и admin / stats / 1 ».

Хотязапускается скрипт Я беру все пути из отдельного массива и использую foreach для сохранения каждого пути:

route('admin/stats/(:num)', array('#title' => 'Statistics',...));

Функция:

function route($path = NULL, $options = NULL) {

static $routes;

    //If no arguments are supplied, return all routes stored.
    if(!isset($path) && !isset($options)) {
        return $routes;
    }

    //return options for path if $path is set.
    if(isset($path) && !isset($options)) {

        //If we have an exact match, return it.
        if(array_key_exists($path, $routes)) {
            return $routes[$path];
        }
        //Else, we need to use RegEx to find the correct route options.
        else {
        $regex = str_replace('/', '\/', $path);
        $regex = '#^' . $regex . '\/?$#';
            //I am trying to get the array key for $route[$path], but it isn't working.

            // route_replace('admin/stats/(:num)') = 'admin/stats/([0-9]+)'.
        $uri_path = route_replace(key($routes[$path])); //route_replace replaces wildcards for regex.
            if(preg_match($regex, $uri_path)) {
                return $routes[$path];
            }
        }
    }

    $routes[$path] = $options;

    return $routes; 
}

Функция замены маршрута:

function route_replace($path) {
    return str_replace(':any', '.+', str_replace(':num', '[0-9]+', $path));
}

Пара ключ / значение в массиве $ routs выглядит следующим образом:

[admin/stats/(:num)] => Array
    (
        [#title] => Statistics //Page title
        [#access] => user_access //function to check if user is authorized 
        [#content] => html_stats //function that returns HTML for the page
        [#form_submit] => form_stats //Function to handle POST submits.
    )

Спасибо за помощь.Это мой первый маршрутизатор, и я не настолько знаком с созданием правильных регулярных выражений.

1 Ответ

1 голос
/ 16 декабря 2011

'admin / stats / (: num)' никогда не будет совпадать с 'admin / stats', так как в вашем "шаблоне" слеш требуется. В pseduo-regex вам нужно сделать что-то вроде 'admin / stats (/: num)'.

В вашем коде также есть несколько ошибок. Эта строка

$uri_path = route_replace(key($routes[$path]));

находится в блоке, который выполняется, когда $ path не является ключом, существующим в $ маршрутах.

Я пытался переписать его, и это, кажется, работает (это просто предложение else):

foreach( array_keys( $routes ) as $route ) {
        $regex = '#^' . $route . '?$#';
        //I am trying to get the array key for $route'$path', but it isn't working.

        // route_replace('admin/stats/(:num)') = 'admin/stats/('0-9'+)'.
        $uri_path = route_replace($regex); //route_replace replaces wildcards for regex.
        if(preg_match($uri_path,$path)) {
            return $routes[$route];
        }
    }

Но для этого требуется, чтобы «admin / stats / (: num)» было «admin / stats (/: num)».

кстати, если у вас его еще нет, вы должны получить отладчик (Zend и xDebug - два наиболее распространенных для PHP). Они могут быть неоценимыми при решении подобных проблем.

Кроме того, спросите себя, нужно ли вам написать роутер, или вы не можете просто использовать один из самых хороших уже там ...

...