1. Откройте файл .htaccess, созданный ранее в папке seophp, и добавьте в него
следующее правило подмены:
RewriteEngine On
# Преобразование my-super.product.html в /product.php?prdduct_id=l23
RewriteRule Amy-super-product\.html$ /product.php?product_id=123
# Преобразование числовых URL-адресов
RewriteRule AProducts/P([0-9]*)\.html$ /product.php?product_id=$l [L]
2. Вернитесь в браузер и введите адрес http: //seophp. example. com/Products/
PI .html. Если все работает так, как надо, вы получите данные, показанные на
рис. 3.7.
3. Можно проверить, чтолтравило работает и для идентификаторов, составленных
из нескольких цифр. Ввод адреса http: / / seophp. example . com/Products/
P123456 .html приведет к результату, приведенному на рис. 3.8.
Поздравляем! Упражнение было довольно коротким, но вы написали свое первое
регулярное выражение! Посмотрите внимательнее на новое правило подмены:
RewriteRule AProducts/P([0-9]*)\.html$ /product.php?product_id=$l [L]
Если это ваш первый опыт работы с регулярными выражениями, то можно и напугаться!
Просто глубоко вдохните и продолжайте чтение: обещаем, что это совсем не
так сложно, как кажется на первый взгляд.
Более последовательное введение в регулярные выражения приведено в приложении А.
Как вы узнали из предыдущего упражнения, в основном команда RewriteRule принимает два аргумента. В данном примере она принимает в качестве третьего аргумента еще и специальный флаг— [L]. Значение этих аргументов будет объяснено ниже.
Первым аргументом RewriteRule является регулярное выражение; оно описывает
соответствующие URL-адреса, которые необходимо подменять. Второй аргумент указывает URL-адреса назначения (подмененные). По сути дела, строка RewriteRule говорит: подменить любой URL, соответствующий шаблону ^Products/P ( [0-9] *) \ .html$, на /product.php?product_id=$l.
Ну а "по-человечески" эта строка гласит: отправлять все запросы, которые выглядят как Products/Pn.html, по адресу /product .php?product_id=n.
Теперь внимательно рассмотрим регулярное выражение, которое описывает соответствующие URL-адреса, требующие подмены. Вот это регулярное выражение:
"Products/P([0-9]*)\.html$
Большинство символов, в том числе и алфавитно-цифровые, означают сами себя
и соответствуют сами себе. Вспомните первое правило RewriteRule, которое было
написано в данной главе для отслеживания my-super-product.html — оно было составлено по большей части из "нормальных" символов.
Но мощность (а иногда и сложность) регулярных выражений обеспечивают специальные символы (метасимволы) наподобие л, . или *, которые имеют специальное значение.
Метасимволы, с которыми вы можете встретиться, перечислены в табл. 3.3.
Учтите, что данная теория описывает регулярные выражения вообще. Подмена L7RL — лишь одна из многих областей, в которой применяются регулярные выражения.
Таблица 3.3. Метасимволы в регулярных выражениях
Метасимвол Описание
^ - Соответствует началу строки. В нашем случае он всегда соответствует началу
URL-адреса. Доменное имя не считается частью URL-адреса, если речь идет о
RewriteRule. О символе Л удобно думать как о "привязке" последующих символов
к началу строки, т.е. он гарантирует их присутствие в начале.
. - Соответствует одному любому символу.
* Указывает, что предыдущий символ или выражение может повторяться ноль или
более раз — т.е. от отсутствия до бесконечного количества раз.
+ - Указывает, что предыдущий символ или выражение может повторяться один или
более раз. Т.е. этот символ или выражение должен присутствовать хотя бы в одном экземпляре.
? - Указывает, предыдущий символ или выражение может повторяться ноль или один раз. Т.е. этот символ или выражение может присутствовать или отсутствовать.
{m, n} - Указывает, что предыдущий символ или выражение может повторяться от m до n раз. т и п — целые числа, причем т должно быть меньше, чем п.
( ) Скобки используются для определения отмеченного выражения (captured expression). Строка, соответствующая выражению в скобках, может быть прочитана в качестве выражения. Скобки также применяются для группировки символов (как в математике), и к такой группе могут применяться операции наподобие *, + или ?.
[ ] Используются для определения класса символов. К примеру, [abc] соответствует
любой из букв а, ь, с. Символ - применяется для определения диапазона символов.
Например, [ a - z ] соответствует любой строчной латинской букве. Если нужно,
чтобы символ - означал сам себя, он должен быть последним перед ]. Многие
метасимволы, заключенные в квадратные скобки, теряют свое специальное значение и интерпретируются буквально.
[^ ] - Аналогично [ ], но только соответствует всему, кроме указанного класса символов. Например, [^ a-c] соответствует всем символам, кроме а, b, с.
$ - Соответствует концу строки. В нашем случае он всегда соответствует концу URL-
адреса. О символе $ удобно думать как о "привязке" последующих символов к
концу строки, т.е. он гарантирует их присутствие в конце.
\ - Обратный слэш используется для литерализации последующего символа.
Применяется тогда, когда нужно, чтобы один из метасимволов имел буквальное,
а не специальное значение. Например, \. соответствует точке, а не любому символу (типичное значение точки в регулярных выражениях). Обратный слэш может литерализовать и сам себя — поэтому если нужен шаблон для соответствия
С:\Windows, то он должен быть записан как C:\\Windows.
Пользуясь табл. 3.3 в качестве справочника, проанализируйте выражение
AProducts/P ([0-9] *) \ .html$. Это выражение начинается с символа А, что означает
начало запрошенного URL (помните, в него не входит доменное имя). Символы
Products/P означают, что следующие символы в URL должны быть именно такими.
Итак, выражение А Products/P соответствует любому URL-адресу, который начинается на Products/P.
Основой всего процесса являются следующие символы— ([0-9] * ) . Часть [0-9]
соответствует любому символу от 0 до 9 (т.е. любой цифре), а последующая звездочка означает, что этот образец может повторяться, чтобы выделить все число, а не отдельную цифру. Скобки, в которые заключено выражение [0-9] *, указывают, что механизм обработки регулярных выражений должен запомнить соответствующую подстроку (т.е. число) в переменной с именем $ 1 (она понадобится для составления подменяющего URL).
В конце выражения имеется подстрока \ . h t m l $ , которая означает, что строка
должна оканчиваться на .html. Символ \ предназначен для литерализации точки, которая должна означать именно точку, а не "любой символ" (значение метасимвола . ) .
Символ $ соответствует концу строки.
Второй аргумент правила— / p r o d u c t . p h p ? p r o d u c t _ i d = $ l — вставляет сохраненные переменные в отображение URL и указывает Web-серверу, что URL-адреса, запрошенные браузерами и соответствующие указанному образцу, должны направляться данному сценарию с числами вместо $1.
Второй аргумент правила RewriteRule записан без помощи языка регулярных выражений.
Но это и не требуется, т.к. он не должен соответствовать ничему. Он просто является формой для подменивающего URL. Единственной частью со специальным значением является переменная $1: ее значение выбирается из выражения в скобках в первом аргументе правила Rewri teRule.
Как видите, это правило действительно подменяет любой запрос URL-адреса, оканчивающегося на Products/Pn.html,на product.php?productID = n— а такой запрос уже может обработать написанный ранее сценарий product.php.
В конце правила подмены можно добавить специальные признаки для нового URL,добавив один или более флагов. Эти признаки специфичны для команды Rewrite Rule и не относятся к регулярным выражениям. Возможные аргументы Rewrite Rule перечислены в табл. 3.4. Эти флаги всегда должны указываться в квадратных скобках в конце отдельного правила.
Некоторые из этих флагов применяются в последующих главах.
Команды Rewrite Rule обрабатываются по порядку так, как они записаны в конфигурационном файле. Если нужно, чтобы правило, которому найдено соответствие,было последним обработанным, необходимо добавить к нему флаг [ L ] , как описано в таблице:
RewriteRule AProducts/P( [ 0 - 9 ] * ) \.html $ ./product.php?product_id=$l [L]
Это особенно удобно при наличии длинного перечня команд RewriteRule , ведь
флаг [ L ] повышает производительность, запрещая модулю mod_rewrite обрабатывать последующие команды RewriteRule после обнаружения соответствия. Обычно именно это и требуется.