Назад | Перейти на главную страницу

Вы видите что-то не так в моем .htaccess?

Мне удалось создать .htaccess файл, который делает то, что я хотел (см. пояснения и вопросы после блока кода):

<IfModule mod_rewrite.c>

RewriteEngine On

#1 If the requested file is not url-mapper.php (to avoid .htaccess loop)
RewriteCond %{REQUEST_FILENAME} (?<!url-mapper\.php)$

#2 If the requested URI does not end with an extension OR if the URI ends with .php*
RewriteCond %{REQUEST_URI} !\.(.*) [OR]
RewriteCond %{REQUEST_URI} \.php.*$ [NC]

#3 If the requested URI is not in an excluded location
RewriteCond %{REQUEST_URI} !^/seo-urls\/(excluded1|excluded2)(/.*)?$

#Then serve the URI via the mapper
RewriteRule .* /seo-urls/url-mapper.php?uri=%{REQUEST_URI} [L,QSA]

</IfModule>

Это то, что .htaccess стоит сделать:

  1. Правило # 1 проверяет, что запрошенный файл не url-mapper.php (чтобы избежать бесконечных циклов перенаправления). Этот файл всегда будет в корне домена.

  2. Правило # 2 то .htaccess должны перехватывать только те URL-адреса, которые не заканчиваются расширением (www.example.com -> поймать | www.example.com/catch-me -> поймать | www.example.com/dont-catch.me -> не лови) и URL-адреса, заканчивающиеся на .php\* файлы (.php, .php4, .php5, .php123, ...).

  3. Правило # 3 некоторые каталоги (и дочерние) могут быть исключены из .htaccess (в таком случае /seo-urls/excluded1 и /seo-urls/excluded2).

  4. Наконец .htaccess кормит картографа скрытый Параметр GET с именем uri содержащий запрошенный URI.

Даже если я протестировал и все работает, я хочу знать, правильно ли то, что я делаю (и является ли это «лучшим» способом сделать это). Я многому научился с этим "проектом", но все еще считаю себя новичком в .htaccess и регулярные выражения, поэтому я хочу трижды проверить его перед запуском в производство ...

<IfModule mod_rewrite.c>

Нет необходимости в <IfModule> обертка. См. Этот вопрос в стеке веб-мастеров: https://webmasters.stackexchange.com/questions/112600/is-checking-for-mod-write-really-needed

#1 If the requested file is not url-mapper.php (to avoid .htaccess loop)
RewriteCond %{REQUEST_FILENAME} (?<!url-mapper\.php)$

Нет необходимости в отрицательном просмотре назад ((?<!). Было бы предпочтительнее просто иметь отрицательное регулярное выражение. т.е. с ! префикс. Например: !^/url-mapper\.php$ (т.е. не "/url-mapper.php") И проверьте REQUEST_URI (полный URL-путь) вместо REQUEST_FILENAME (абсолютный путь к файловой системе).

Однако вы заявляете, что «этот файл всегда будет в корне домена», но вы переписываете на /seo-urls/url-mapper.php - который не находится в корне домена.

Итак, это должно быть написано строго так:

RewriteCond %{REQUEST_URI} !^/seo-urls/url-mapper\.php$

Если вы не уверены, есть только один url-mapper.php файл в вашей системе, то регулярное выражение может быть уменьшено до !/url-mapper\.php$.

Или проверьте это в RewriteRule шаблон вместо этого (поскольку вы больше ничего не делаете с RewriteRule шаблон В настоящее время). Это было бы незначительно более эффективным.

#2 If the requested URI does not end with an extension OR if the URI ends with .php*
RewriteCond %{REQUEST_URI} !\.(.*) [OR]
RewriteCond %{REQUEST_URI} \.php.*$ [NC]

Первое условие слишком общее - оно захватывает любой URL-адрес, который просто содержит точку в любом месте URL-пути, а не просто расширение файла. Также нет необходимости в подшаблонах захвата. Предполагая, что расширение файла составляет от 2 до 4 символов, тогда шаблон вроде !\.\w{2,4}$ точнее ловил бы только расширения файлов.

Как правило, регулярное выражение должно быть максимально ограничительным. Второе условие, что Спички .php расширение (я) можно сделать более ограничительным, в настоящее время оно соответствует .php везде в URL-пути. Например: \.php\d{0,4}$ - хотя на самом деле у вас, вероятно, есть не более 1 цифры после .php, так \.php\d?$ наверное было бы лучше.

Я также сомневаюсь, что NC (без учета регистра) здесь действительно требуется флаг. Вам действительно нужно соответствовать .PHP или .PhP?

#3 If the requested URI is not in an excluded location
RewriteCond %{REQUEST_URI} !^/seo-urls\/(excluded1|excluded2)(/.*)?$

Хорошо, но конечный (/.*)?$ лишнее. Вы сопоставляете все, что просто начинается /seo-urls/excluded1 и т.д. Кроме того, нет необходимости использовать обратную косую черту с escape-чертой (любопытно, что вы избежали средней косой черты, но не двух других).

#Then serve the URI via the mapper
RewriteRule .* /seo-urls/url-mapper.php?uri=%{REQUEST_URI} [L,QSA]

Хорошо, хотя регулярное выражение .* (который соответствует всему) можно упростить до ^ - что хорошо для всего, но на самом деле ничего не соответствует - это все, что вам нужно.

Однако я упомянул вверху о выполнении url-mapper.php проверить в RewriteRule шаблон вместо. Итак, это будет написано:

RewriteRule !^seo-urls/url-mapper\.php$ /seo-urls/url-mapper.php?uri=%{REQUEST_URI} [L,QSA]

В RewriteRule шаблон обрабатывается первым, перед любым из условий, поэтому всегда предпочтительно делать то, что вы можете в RewriteRule директиву, а не разделять ее на другое условие.

Резюме

Объединив вышеупомянутые моменты, мы имеем:

RewriteEgnine On

#2 If the requested URI does not end with an extension OR if the URI ends with .php*
RewriteCond %{REQUEST_URI} !\.\w{2,4}$ [OR]
RewriteCond %{REQUEST_URI} \.php\d?$

#3 If the requested URI is not in an excluded location
RewriteCond %{REQUEST_URI} !^/seo-urls\/(excluded1|excluded2)

#Then serve the URI via the mapper
RewriteRule !^seo-urls/url-mapper\.php$ /seo-urls/url-mapper.php?uri=%{REQUEST_URI} [QSA,L]

2a разрешит /some.dir/file из-за "." посередине. Вы можете захотеть что-то вроде !\..[1,3], это будет зависеть от структуры вашего файла / каталога.

В RewriteRules нормально использовать сопоставление подстановки вместо имен переменных:
RewriteRule (.*) /seo-urls/url-mapper.php?uri=$5 [L,QSA]
Обратите внимание, что это $5 потому что в настоящее время у вас есть шаблоны соответствия для всех ваших условий.