2013-04-13 4 views
1

В PHP маршрутизация klein будет соответствовать как можно большему количеству маршрутов. 2 маршрута, которые я настроил, противоречат друг другу. К ним относятся:regex matching url

$route1: '/websites/[i:websiteId]/users/[i:id]?' 

и

$route2: '/websites/[i:websiteId]/users/[a:filename].[json|csv:extension]?' 

Это URL я пытаюсь соответствовать, который я думаю, должен соответствовать первому и не второй, является:

/api/v1-test/websites/100/users/4 

Регулярное выражение для этих двух:

$regex1: `^/api(?:/(v1|v1-test))/websites(?:/(?P<websiteId>[0-9]++))/users(?:/(?P<id>[0-9]++))?$` 

$regex2: `^/api(?:/(v1|v1-test))/websites(?:/(?P<websiteId>[0-9]++))/users(?:/(?P<filename>[0-9A-Za-z]++))(?:\.(?P<extension>json|csv))?$` 

Я имею в виду, что это не соответствует, если нет «.csv» или «.json». Проблема в том, что он соответствует обеим маршрутам. Для второго результирующего имени файла будет «4», а расширение будет пустым.

Отправка /api/v1-test/websites/100/users/users.csv работает правильно и соответствует только второму маршруту.

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

ответ

0

Этот бит здесь

(?:\.(?P<extension>json|csv))? 

в конце вашего второго регулярное выражение заставляет его соответствовать или нет там имя файла из-за ? в самом конце. Вопросительные знаки означают 0 or 1 of the previous expression. Избавьтесь от этого и, по крайней мере, строки будут соответствовать только этому регулярному выражению, когда у них есть расширение.

Чтобы сделать это изменение, просто удалите знак вопроса из вашего второго маршрута, например, так:

$route2: '/websites/[i:websiteId]/users/[a:filename].[json|csv:extension]' 
+0

я сделал не так много, как это ответ, когда я впервые прочитал. Мое наивное понимание заключается в том, что? говорит, что что-то после этого принимается за параметры. –

+0

Вы правы, что? может использоваться для [маркировки подшаблона] (http://www.php.net/manual/en/regexp.reference.subpatterns.php). Но бывает так, что в синтаксисе регулярного выражения PHP (который использует система маршрутизации Klein) знак вопроса использует более одного использования. Последний ? в вашем маршруте интерпретируется как «0 или 1» [метасимвол] (http://www.php.net/manual/en/regexp.reference.meta.php). – jmeas

+0

Фактически, последний пример маршрута в [Klein readme] (https://github.com/chriso/klein.php#routing) имеет очень похожий путь к тому, что вы описали, явно говоря, что это приводит к расширению файла опций , Если вы хотите, чтобы route2 требовал расширения, вы должны удалить завершающий символ '?'. – jmeas

0

Проблема заключается в том, что match_type определяется на самом деле ... причудливо:

$match_types = array(
      'i' => '[0-9]++', 
      'a' => '[0-9A-Za-z]++', 
[...] 

Таким образом, вы не можете действительно захватить последовательность, соответствующую [a-zA-Z] ... Единственный вариант, который я вижу, - использовать 3 маршрута:

$route1: '/websites/[i:websiteId]/users/[i:id]?' 
$route2: '/websites/[i:websiteId]/users/[a:filename]' 
$route3: '/websites/[i:websiteId]/users/[a:filename].[json|csv:extension]' 

И назначать одни и те же действия для маршрутов 2 и 3. Тогда вы бы это:

  • /api/v1-test/websites/100/users/ подобран 1
  • /api/v1-test/websites/100/users/4 подобран 1
  • /api/v1-test/websites/100/users/test подобрано 2
  • /api/v1-test/websites/100/users/test.csv соответствует 3

Это похоже на поведение, которое вы хотели.

(проще) решение

Abother бы воспользоваться этой частице документации:

Routes automatically match the entire request URI. 
If you need to match only a part of the request URI 
or use a custom regular expression, use the @ operator.

Вы можете определить свои маршруты, как это:

$route1: '@/websites/[0-9]+/users/[0-9]*$' 
$route1: '@/websites/[0-9]+/users/[a-zA-Z]+(\.[a-zA-Z]+)?$' 
+0

Философски, мне понравился этот ответ лучше. Я думал, что использование нескольких маршрутов имеет потенциал. Но мне все еще нужно? из-за всех параметров, следующих за ним. Поэтому я не понимаю, как ваше изменение не позволяет пользователю/4 сопоставлять маршрут 3. –

+0

Итак, я ошибаюсь. PHP понимает? в URL-адресе без добавления его на маршрут. –

+0

@BradWhite: ну, на самом деле, когда я снова прочитаю свой ответ, я думаю, что первое решение не будет работать после всех ... user/4 не будет соответствовать маршруту 3, потому что для него требуется расширение после имени файла. однако пользователь/4 по-прежнему будет соответствовать маршрутам 1 и 2, я думаю. Однако я уверен, что второе решение - именно то, что вы ищете. – m4573r