2015-05-24 4 views
1

Я пытаюсь сделать маршрутизатор с истинным соответствием с помощью регулярного выражения, но я всегда зациклился на том, как загружаются маршруты.Regex True Match Behavior

Если у меня есть маршруты, как

  • /: любой
  • /блог /: любой
  • /блог/категория /: любой

Первый маршрут будет всегда сбываются вместо использования второго маршрута или третьего.

$data = array(); 

foreach($this->routes as $route => $rData) { 

    if(strpos($route, ':') !== false) { 
     foreach($this->tokens as $token => $value) { 
      $route = str_replace($token, $value, $route); 
     } 
    } 

    if(preg_match('#^'.$route.'$#', $url, $matches)) { 
     $data['params'] = array_slice($matches, 1); 
     $data = array_merge($rData, $data); 
     break; 
    } 
} 

Маршруты:

$routes = array(
    '/:any' => callback, 
    '/blog/:any' => callback, 
    '/blog/category/:any' => callback 
); 

лексем:

$tokens = array(
    ':num' => '([0-9]+)', 
    ':any' => '(.+)' 
); 

Адрес:

$url = $_SERVER['QUERY_STRING']; 

Как я могу сделать регулярное выражение/preg_match, чтобы получить правильный матч маршрут?

+0

Возможно, было бы полезно показать, как «$ this-> routes», '$ this-> tokens' и' $ url' заполняются или, по крайней мере, примерные значения для всех этих переменных, чтобы лучше понять, что такое происходит. –

+0

Я думаю, что прямо, как дела, но я добавил их тоже. – Filipe

ответ

0

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

Yoy должен написать их так:

$routes = array(
    '/blog/category/:any' => callback 
    '/blog/:any' => callback, 
    '/:any' => callback, 
); 

Это не ошибка кода. Это просто логика исполнения

UPDATE родилась из дискуссии с автором вопроса

Предположим, что мы хотим, чтобы найти соответствие с наибольшим количеством сегментов:

$routes = array(
    '/:any' => 'callback1', 
    '/blog/:any' => 'callback2', 
    '/blog/category/:any' => 'callback' 
); 

foreach ($routes as $in => $out) 
    $counts[$in] = count(explode('/', $in)); 
arsort($counts); 
foreach ($counts as $in => $count) 
    $newroutes[$in] = $routes[$in]; 

var_dump($newroutes); 

возвращает

array(3) { 
    ["/blog/category/:any"]=> 
    string(8) "callback" 
    ["/blog/:any"]=> 
    string(9) "callback2" 
    ["/:any"]=> 
    string(9) "callback1" 
} 

затем использовать этот newroutes массив

+0

Верно, но если вы находитесь в ситуации с модулем, вы не будете контролировать, как модули устанавливаются. Например, если категория модуля установлена ​​после блога, маршруты блога будут перезаписывать маршруты категорий. Должно быть решение для этого. – Filipe

+0

@Filipe То, что я написал, - это практика, используемая во многих cms. Если вы идете по маршрутам и найдете 10 матчей, то какой из них вы будете выполнять. У вас есть ответ? – splash58

+0

@Filipe Если модуль хочет динамически добавлять маршрут, он не должен расширять предыдущие шаблоны, а создавать собственные, такие как '/ auth', например – splash58