PHP и Apache - синтаксический анализ mod_rewrite url
-
19-09-2019 - |
Вопрос
У меня есть apache моего сервера, настроенный на перенаправление каждого запроса в index.php , так что я могу использовать URL-адреса, такие как :
http://www.website.com/about/us
Теперь мне нужно проанализировать URL-адрес, чтобы определить, существует ли каждый маршрут и чего от него ожидать, чтобы я мог настроить таблицу базы данных для сохранения маршрутов, и чтобы мои клиенты могли редактировать свои маршруты так, как им нравится.Дело в том, что пока я не в состоянии выполнить синтаксический анализ.
Вот мой код :
$uri = 'about/us';
$regex = '(page(/<action>))';
if ( ! preg_match($regex, $uri, $matches)) {
echo 'the route doesn\'t match';
exit();
}
Он всегда показывает это эхо-сообщение.Что я делаю не так?
Редактировать :
Причина, по которой мне нужно регулярное выражение, заключается в следующем.Представьте, что у меня есть сегмент URL, подобный :
/user/yoda
Регулярное выражение здесь было бы полезно для анализа первого аргумента как действия или страницы, а второго как ключа, который допускает только определенный набор символов, например, если я хочу ожидать, в данном случае, что второй параметр будет соответствовать только "_-azAZ09", что-то вроде этого.Другими словами, набор выражений регулярных выражений я бы сравнил с uri, чтобы определить, соответствует ли какое-либо из них uri, и определить действие, которое следует предпринять с этого момента.Использование функции explode заставило бы меня оценивать сегменты uri позже в коде, чего я хотел бы избежать.Если нет совпадения с uri, немедленно перенаправьте страницу на страницу 404 и прервите операцию.Не знаю , ясно ли я выразился ..
Решение
Вместо использования регулярных выражений, почему бы просто не разделить входящий URI?
$uri = 'about/us';
list($page, $action) = explode('/', $uri);
Если вам нужно больше двух, просто удалите список:
$pagePath = explode('/', $uri);
Но, если вы настаивать при использовании регулярных выражений это будет делать:
$regex = '#(?P<page>.*)/(?P<action>.*)#';
Однако он не предлагает вам ничего особенного, за исключением того, что $matches теперь будет содержать $matches['page']
и $matches['action']
- но если вам действительно это нужно, вы можете использовать list()
как показано выше.
Использование функции explode заставило бы меня оценить сегменты uri позже в коде, которого я хотел бы избежать
Вместо того, чтобы проверять допустимость страницы по ее набору символов, почему бы не составить таблицу поиска списка допустимых страниц и просто использовать php in_array
что намного быстрее, чем регулярное выражение?Извлечение сегментов URL в массив позволит вам в кратчайшие сроки выполнить проверку многомерных массивов.
Другие советы
Я думаю, что регулярное выражение должно быть окружено символом;например '@(page(/<action>))@'
.Смотрите примеры в http://php.net/preg_match
Если вам по какой-то причине абсолютно необходимо использовать регулярное выражение, попробуйте следующее:
$uri = 'about/us';
$regex = '~(?<path>[^/]+)/(?<action>.+)~';
var_dump($matches);
Какие результаты:
array(5) {
[0]=>
string(8) "about/us"
["path"]=>
string(5) "about"
[1]=>
string(5) "about"
["action"]=>
string(2) "us"
[2]=>
string(2) "us"
}
Однако это сработает только тогда, когда компонент path опустится только на один уровень!