«Красивые ссылки» - это часто запрашиваемая тема, но она редко получает полное объяснение. mod_rewrite - это один из способов создания "красивых ссылок", но он сложен, а его синтаксис очень краток, его трудно понять, а документация предполагает определенный уровень владения HTTP. Может ли кто-нибудь простыми словами объяснить, как работают "красивые ссылки" и как можно использовать mod_rewrite для их создания?
Другие распространенные имена, псевдонимы, термины для чистых URL-адресов: URL- адреса RESTful , удобные для пользователя URL-адреса, URL-адреса, оптимизированные для SEO , сегментирование и URL-адреса MVC (вероятно, неправильное название)
apache
.htaccess
mod-rewrite
friendly-url
обмануть
источник
источник
reference-mod-rewrite-url-rewriting-explained
что слаг,/questions/20563772/reference-mod-rewrite-url-rewriting-explained
это красивый URL..htaccess
иmod-rewrite
метки должны быть обновлены , чтобы включить ссылку на этот вопрос, поскольку он охватывает большую часть того, что предлагается на регулярной основе. Мысли?Ответы:
Чтобы понять, что такое mod_rewrite, вам сначала нужно понять, как работает веб-сервер. Веб-сервер отвечает на HTTP-запросы . HTTP-запрос на самом базовом уровне выглядит так:
Это простой запрос браузера к веб-серверу, запрашивающий у него URL
/foo/bar.html
. Важно подчеркнуть, что он не запрашивает файл , он запрашивает просто произвольный URL. Запрос также может выглядеть так:Это такой же действительный запрос на URL, и более очевидно, что он не имеет ничего общего с файлами.
Веб-сервер - это приложение, которое прослушивает порт, принимает HTTP-запросы, поступающие через этот порт, и возвращает ответ. Веб-сервер полностью свободен отвечать на любой запрос любым способом / любым способом, который вы настроили для его ответа. Этот ответ не является файлом, это HTTP-ответ, который может иметь или не иметь ничего общего с физическими файлами на любом диске. Веб-сервер не обязательно должен быть Apache, существует множество других веб-серверов, которые представляют собой просто программы, которые работают постоянно и подключены к порту, который отвечает на HTTP-запросы. Вы можете написать его сами. Этот абзац был призван отвлечь вас от любого представления о том, что URL-адреса напрямую равны файлам, что действительно важно понять. :)
Конфигурация по умолчанию большинства веб-серверов заключается в поиске файла, соответствующего URL-адресу на жестком диске. Если корень документа сервера установлен, скажем, на
/var/www
, он может проверить,/var/www/foo/bar.html
существует ли файл, и обслужить его, если это так. Если файл заканчивается на «.php», он вызовет интерпретатор PHP, а затем вернет результат. Вся эта ассоциация полностью настраивается; файл не обязательно должен заканчиваться на «.php», чтобы веб-сервер мог запустить его через интерпретатор PHP, а URL-адрес не должен соответствовать какому-либо конкретному файлу на диске, чтобы что-то произошло.mod_rewrite - это способ переписать внутреннюю обработку запросов. Когда веб-сервер получает запрос URL-адреса
/foo/bar
, вы можете переписать этот URL-адрес во что-то другое, прежде чем веб-сервер будет искать файл на диске, соответствующий ему. Простой пример:Это правило гласит, что всякий раз, когда запрос соответствует «/ foo / bar», переписывайте его в «/ foo / baz». Затем запрос будет обработан так, как если бы
/foo/baz
он был запрошен. Это можно использовать для различных эффектов, например:Это правило соответствует чему-либо (
.*
) и захватывает его ((..)
), а затем перезаписывает его, добавляя «.html». Другими словами, если это/foo/bar
был запрошенный URL, он будет обработан так, как если/foo/bar.html
бы был запрошен. См. Http://regular-expressions.info для получения дополнительной информации о сопоставлении, захвате и замене регулярных выражений.Еще одно часто встречающееся правило:
Это, опять же, сопоставляет что-либо и перезаписывает его в файл index.php с первоначально запрошенным URL-адресом, добавленным в
url
параметр запроса. То есть, для любого и всех поступающих запросов выполняется файл index.php, и этот файл будет иметь доступ к исходному запросу$_GET['url']
, поэтому он может делать с ним все, что захочет.Сначала вы помещаете эти правила перезаписи в файл конфигурации вашего веб-сервера . Apache также позволяет * помещать их в файл, который называется
.htaccess
в корне вашего документа (то есть рядом с вашими .php файлами).* Если это разрешено основным файлом конфигурации Apache; это необязательно, но часто включается.
Что mod_rewrite ничего не делать
mod_rewrite не делает все ваши URL "красивыми" волшебным образом. Это распространенное заблуждение. Если у вас есть эта ссылка на вашем веб-сайте:
mod_rewrite ничего не может сделать, чтобы сделать это красивым. Чтобы сделать эту ссылку красивой, вам необходимо:
Измените ссылку на красивую ссылку:
Используйте mod_rewrite на сервере, чтобы обработать запрос к URL-адресу,
/my/pretty/link
используя любой из описанных выше методов.(Можно использовать
mod_substitute
вместе для преобразования исходящих HTML-страниц и содержащихся в них ссылок. Хотя обычно это требует больше усилий, чем просто обновление ваших HTML-ресурсов.)Mod_rewrite может многое сделать, и вы можете создать очень сложные правила сопоставления, включая объединение нескольких перезаписей, проксирование запросов к совершенно другой службе или машине, возвращение определенных кодов состояния HTTP в качестве ответов, перенаправление запросов и т. Д. Это очень мощное средство, которое может использоваться для Отлично, если вы понимаете фундаментальный механизм HTTP-запроса-ответа. Это не автоматически делает ваши ссылки довольно.
См. Официальную документацию для всех возможных флагов и опций.
источник
Чтобы расширить ответ deceze , я хотел бы привести несколько примеров и объяснение некоторых других функций mod_rewrite.
Все приведенные ниже примеры предполагают, что вы уже включили
RewriteEngine On
в свой.htaccess
файл.Переписать пример
Возьмем этот пример:
Правило разделено на 4 части:
RewriteRule
- запускает правило перезаписи^blog/([0-9]+)/([A-Za-z0-9-\+]+)/?$
- Это называется шаблоном, но я буду называть его левой частью правила - то, что вы хотите переписать.blog/index.php?id=$1&title=$2
- называется подстановкой, или правая часть правила перезаписи - то, что вы хотите переписать[NC,L,QSA]
- это флаги правила перезаписи, разделенные запятой, о которых я расскажу позже.Вышеупомянутая перезапись позволит вам ссылаться на что-то вроде,
/blog/1/foo/
и оно действительно загрузится/blog/index.php?id=1&title=foo
.Левая часть правила
^
указывает на начало имени страницы - поэтому он будет перезаписан,example.com/blog/...
но неexample.com/foo/blog/...
(…)
круглых скобок представляет собой регулярное выражение, которое мы можем записать как переменную в правой части правила. В этом примере:([0-9]+)
- соответствует строке длиной не менее 1 символа и только числовыми значениями (например, 0–9). На это можно ссылаться$1
в правой части правила.-
или+
(примечание+
экранируется обратной косой чертой, так как без нее это будет выполняться как регулярное выражение характер повторения ). На это можно ссылаться$2
в правой части правила.?
означает, что предыдущий символ является необязательным, поэтому в этом случае оба/blog/1/foo/
и/blog/1/foo
будут перезаписаны в одном месте$
указывает, что это конец строки, которую мы хотим сопоставитьФлаги
Это параметры, которые добавляются в квадратные скобки в конце правила перезаписи для указания определенных условий. Опять же, есть много разных флагов, о которых вы можете прочитать в документации , но я рассмотрю некоторые из наиболее распространенных флагов:
Флаг отсутствия регистра означает, что правило перезаписи нечувствительно к регистру, поэтому для приведенного выше примера правила это будет означать, что оба
/blog/1/foo/
и/BLOG/1/foo/
(или любой его вариант) будут сопоставлены.Последний флаг указывает, что это последнее правило, которое следует обработать. Это означает, что если и только если это правило совпадает, никакие другие правила не будут оцениваться в текущем прогоне обработки перезаписи. Если правило не совпадает, все остальные правила будут проверены в обычном порядке. Если вы не установите этот
L
флаг, все следующие правила будут применены к перезаписанному URL впоследствии.Начиная с Apache 2.4, вы также можете использовать
[END]
флаг. Правило сопоставления с ним полностью прекратит дальнейшую обработку псевдонима / перезаписи. (В то время как[L]
флаг часто может запускать второй раунд, например, при перезаписи в подкаталоги или из них.)Флаг добавления строки запроса позволяет нам передавать дополнительные переменные по указанному URL-адресу, которые будут добавлены к исходным параметрам get. В нашем примере это означает, что что-то вроде
/blog/1/foo/?comments=15
загрузится/blog/index.php?id=1&title=foo&comments=15
Этот флаг я не использовал в приведенном выше примере, но я подумал, что о нем стоит упомянуть. Это позволяет указать перенаправление http с возможностью включения кода состояния (например
R=301
). Например, если вы хотите выполнить 301 редирект на / myblog / в / блог /, вы просто напишите правило примерно так:Условия перезаписи
Условия перезаписи делают перезапись еще более мощной, позволяя указать перезапись для более конкретных ситуаций. Есть много условий, о которых вы можете прочитать в документации , но я коснусь нескольких распространенных примеров и объясню их:
Это очень распространенная практика, при которой к вашему домену добавляется
www.
(если его еще нет) и выполняется перенаправление 301. Например, загрузкаhttp://example.com/blog/
перенаправит вас наhttp://www.example.com/blog/
Это немного реже, но это хороший пример правила, которое не выполняется, если имя файла - это каталог или файл, существующий на сервере.
%{REQUEST_URI} \.(jpg|jpeg|gif|png)$ [NC]
будет выполнять перезапись только для файлов с расширением jpg, jpeg, gif или png (без учета регистра).%{REQUEST_FILENAME} !-f
проверит, существует ли файл на текущем сервере, и выполнит перезапись, только если это не так.%{REQUEST_FILENAME} !-d
проверит, существует ли файл на текущем сервере, и выполнит перезапись, только если это не так.источник
Ссылки
У Stack Overflow есть много других замечательных ресурсов для начала:
удалить косую черту в
^/
префиксах шаблонов для.htaccess
использования.)И даже удобные для новичков обзоры регулярных выражений:
Часто используемые заполнители
.*
соответствует чему угодно, даже пустой строке. Вы не хотите использовать этот шаблон везде, но часто в последнем резервном правиле.[^/]+
чаще используется для сегментов пути. Соответствует чему угодно, кроме косой черты.\d+
соответствует только числовым строкам.\w+
соответствует буквенно-цифровым символам. Это в основном сокращение от[A-Za-z0-9_]
.[\w\-]+
для сегментов пути в стиле «слизняк», используя буквы, цифры, тире-
и_
[\w\-.,]+
добавляет точки и запятые. Предпочитайте экранированное\-
тире в[…]
классах символов.\.
обозначает буквальный период. В противном случае.
за пределами[…]
будет заполнитель для любого символа.Каждый из этих заполнителей обычно заключен в
(…)
круглые скобки как группа захвата. И весь узор часто в^………$
маркерах начала + конца. Цитирование «паттернов» необязательно.RewriteRules
Следующие ниже примеры ориентированы на PHP и немного более инкрементальные, их легче адаптировать для подобных случаев. Это просто резюме, часто ссылки на другие варианты или подробные вопросы и ответы.
Статическое отображение
/contact
,/about
Сократить несколько имен страниц до внутренних файловых схем проще всего:
Числовые идентификаторы
/object/123
http://example.com/article/531
Также легко ввести ярлыки, подобные существующим сценариям PHP. Числовой заполнитель можно просто переназначить на$_GET
параметр:Заполнители в стиле слагов
/article/with-some-title-slug
Вы можете легко расширить это правило, чтобы разрешить
/article/title-string
заполнители:Обратите внимание, что ваш сценарий должен иметь возможность (или быть адаптированным) для сопоставления этих заголовков с идентификаторами базы данных. Только RewriteRules не может создать или угадать информацию из воздуха.
Слизни с числовыми префиксами
/readable/123-plus-title
Поэтому
/article/529-title-slug
на практике часто встречаются смешанные пути:Теперь вы можете просто пропустить передачу
title=$2
, потому что ваш скрипт обычно в любом случае будет полагаться на идентификатор базы данных.-title-slug
Становится произвольным украшением URL.Единообразие с альтернативными списками
/foo/…
/bar/…
/baz/…
Если у вас есть аналогичные правила для нескольких виртуальных путей к страницам, вы можете сопоставить и сжать их с помощью
|
альтернативных списков. И снова просто переназначьте их внутренним параметрам GET:Вы можете разделить их на отдельные,
RewriteRule
если это станет слишком сложным.Отправка связанных URL-адресов в разные серверные части
/date/SWITCH/backend
Более практическое использование альтернативных списков - отображение путей запросов в отдельные сценарии. Например, чтобы предоставить единые URL-адреса для старого и нового веб-приложения на основе дат:
Это просто переназначает сообщения 2009-2011 годов в один скрипт, а все остальные годы неявно - в другой обработчик. Обратите внимание на более конкретное правило . Каждый сценарий может использовать разные параметры GET.
Другие разделители, кроме
/
косой черты пути/user-123-name
Чаще всего вы видите RewriteRules для имитации структуры виртуальных каталогов. Но вас не заставляют быть нетворческим. Вы также можете использовать
-
дефисы для сегментации или структурирования.Для тоже распространенной
/wiki:section:Page_Name
схемы:Иногда целесообразно чередовать
/
-делитель и /:
или даже.
в одном правиле. Или снова используйте два правила RewriteRule, чтобы сопоставить варианты с разными сценариями.Необязательный завершающий
/
слэш/dir
=/dir/
Выбирая пути в стиле каталогов, вы можете сделать его доступным с финальным /
Теперь это обрабатывает оба
http://example.com/blog/123
и/blog/123/
. И этот/?$
подход легко добавить к любому другому RewriteRule.Гибкие сегменты для виртуальных путей
.*/.*/.*/.*
Большинство правил, с которыми вы столкнетесь, сопоставляют ограниченный набор
/…/
сегментов пути ресурса с отдельными параметрами GET. Однако некоторые сценарии обрабатывают переменное количество параметров . Механизм регулярных выражений Apache не позволяет опционально использовать произвольное их количество. Но вы можете легко расширить его до блока правил:Если вам нужно до пяти сегментов пути, скопируйте эту схему в пять правил. Конечно, вы можете использовать более конкретный
[^/]+
заполнитель. Здесь порядок не так важен, поскольку ни одно не перекрывается. Так что иметь в первую очередь наиболее часто используемые пути - это нормально.В качестве альтернативы вы можете использовать здесь параметры массива PHP через
?p[]=$1&p[]=$2&p[]=3
строку запроса - если ваш сценарий просто предпочитает их предварительное разбиение. (Хотя чаще всего используется правило для всех и позволяет самому сценарию расширять сегменты из REQUEST_URI.)См. Также: Как преобразовать сегменты пути URL в пары ключ-значение строки запроса?
Необязательные сегменты
prefix/opt?/.*
Обычный вариант - иметь в правиле необязательные префиксы . Обычно это имеет смысл, если у вас есть статические строки или более ограниченные заполнители:
Теперь более сложный шаблон
(?:/([^/])+)?
просто обертывает группу без захвата(?:…)
и делает ее необязательной)?
. Содержащийся заполнитель([^/]+)
будет шаблоном подстановки$2
, но будет пустым, если нет среднего/…/
пути.Захватить остаток
/prefix/123-capture/…/*/…whatever…
Как было сказано ранее, вам не всегда нужны слишком общие шаблоны перезаписи. Однако имеет смысл комбинировать статические и конкретные сравнения с
.*
иногда.Это опционально
/…/…/…
делало любые конечные сегменты пути. Что, конечно же, требует, чтобы сценарий обработки разделял их и изменял извлеченные параметры непосредственно (что и делают фреймворки Web- "MVC" ).Завершающие "расширения" файла
/old/path.HTML
URL-адреса действительно не имеют расширений файлов. Вот о чем вся эта ссылка (= URL-адреса являются виртуальными локаторами, не обязательно прямым образом файловой системы). Однако, если раньше у вас было сопоставление файлов 1: 1, вы можете создать более простые правила:
Другие распространенные применения - это переназначение устаревших
.html
путей на новые.php
обработчики или просто смещение имен каталогов только для отдельных (фактических / реальных) файлов.Пинг-понг (перенаправляет и переписывает в унисон)
/ugly.html
← →/pretty
Итак, в какой-то момент вы переписываете свои HTML-страницы так, чтобы они содержали только красивые ссылки, как показано deceze . Тем временем вы по-прежнему будете получать запросы на старые пути, иногда даже из закладок. В качестве обходного пути вы можете использовать браузеры для пинг-понга для отображения / установки новых URL-адресов.
Этот распространенный трюк заключается в отправке перенаправления 30x / Location всякий раз, когда входящий URL следует устаревшей / уродливой схеме именования. Затем браузеры повторно запросят новый / красивый URL-адрес, который впоследствии будет перезаписан (только внутри) на исходное или новое местоположение.
Обратите внимание, как в этом примере используется просто
[END]
вместо[L]
безопасного чередования. Для более старых версий Apache 2.2 вы можете использовать другие обходные пути, помимо переназначения параметров строки запроса, например: перенаправить некрасивый URL-адрес на красивый, переназначить обратно на уродливый путь без бесконечных цикловПробелы ␣в узорах
/this+that+
Это не так красиво в адресных строках браузера, но вы можете использовать пробелы в URL-адресах. Для шаблонов перезаписи используйте
\␣
пробелы с обратной косой чертой . В"
противном случае просто цитируйте весь шаблон или замену:Клиенты сериализуют URL-адреса с пробелами
+
или%20
вместо них. Однако в RewriteRules они интерпретируются с помощью буквальных символов для всех относительных сегментов пути.Частые дубликаты:
Все для центрального диспетчера / фронт-контроллера скрипта
Что часто используется фреймворками PHP или скриптами WebCMS / портала. Фактическое разделение пути затем обрабатывается в PHP с использованием
$_SERVER["REQUEST_URI"]
. Таким образом, концептуально это в значительной степени противоположно обработке URL-адресов "per mod_rewrite". (Просто используйтеFallBackResource
вместо этого.)Удалить
www.
из имени хостаОбратите внимание, что это не копирует строку запроса и т. Д.
См. Также:
· Перезапись URL-адресов для различных протоколов в .htaccess
· Универсальный htaccess перенаправляет www на не-www
· .htaccess - как принудительно использовать "www". в общем виде?
Обратите внимание, что комбинации RewriteCond / RewriteRule могут быть более сложными, при этом совпадения (
%1
и$1
) взаимодействуют даже в обоих направлениях:Руководство Apache - введение mod_rewrite , Copyright 2015 The Apache Software Foundation, AL-2.0
Перенаправить на
HTTPS://
См. Также: https://wiki.apache.org/httpd/RewriteHTTPToHTTPS.
«Удаление» расширения PHP
См. Также: Удаление расширения .php с помощью mod_rewrite
Смещение старых путей .html к сценариям .php
См. Http://httpd.apache.org/docs/2.4/rewrite/remapping.html#backward-compatibility
Перепишите с URL-адреса типа "/ page" в сценарий, например "/index.php/page"
См. Mod_rewrite, php и файл .htaccess
Перенаправить поддомен в папку
См. Как я могу заставить мой htaccess работать (поддомены)?
Распространенные
.htaccess
подводные камниТеперь отнеситесь к этому с недоверием. Не каждый совет можно обобщить на все контексты. Это просто краткое изложение хорошо известных и нескольких неочевидных камней преткновения:
Включить
mod_rewrite
и.htaccess
Чтобы использовать RewriteRules в файлах конфигурации для каждого каталога, вы должны:
Убедитесь, что ваш сервер
AllowOverride All
включен . В противном случае ваши.htaccess
директивы для каждого каталога будут проигнорированы, и RewriteRules не будет работать.Очевидно ,
mod_rewrite
включили вhttpd.conf
разделе ваших модулей.Закрепите каждый список правил
RewriteEngine On
неподвижным. В то время как mod_rewrite неявно активно<VirtualHost>
и<Directory>
разделы, в каждый каталог.htaccess
файлов нужно это индивидуально вызвал.Начальная косая черта
^/
не совпадаетВы не должны начинать свои
.htaccess
шаблоны RewriteRule^/
обычно с:Это часто можно увидеть в старых руководствах. И это было правильно для старых версий Apache 1.x. В настоящее время пути запросов в RewriteRules полностью зависят от каталога
.htaccess
. Просто оставьте/
вывод.· Обратите внимание, что ведущая косая черта все еще верна в
<VirtualHost>
разделах. Вот почему вы часто видите его^/?
опциональным для обеспечения четности правил.· Или при использовании
RewriteCond %{REQUEST_URI}
вы все еще соответствуете ведущему/
.· См. Также Webmaster.SE: Когда в шаблонах mod_rewrite нужен ведущий слэш (/)?
<IfModule *>
обертки ушли!Вы, наверное, видели это на многих примерах:
<VirtualHost>
разделах - если он был объединен с другим резервным вариантом, например ScriptAliasMatch. (Но этого никто никогда не делает)..htaccess
наборов правил по умолчанию во многих проектах с открытым исходным кодом. Там это просто резерв, и по умолчанию "уродливые" URL-адреса остаются.Однако обычно этого не требуется в ваших собственных
.htaccess
файлах.500
ошибок HTTP . Обычно он404
вместо этого награждает пользователей ошибками HTTP . (Не намного удобнее, если задуматься.)Не используйте без
RewriteBase
необходимостиМногие примеры копирования + вставки содержат
RewriteBase /
директивы. Что в любом случае является неявным значением по умолчанию. Так что на самом деле вам это не нужно. Это обходной путь для причудливых схем перезаписи VirtualHost и неправильных путей DOCUMENT_ROOT для некоторых общих хостеров.Имеет смысл использовать отдельные веб-приложения в более глубоких подкаталогах. В таких случаях он может сократить шаблоны RewriteRule. Обычно лучше отдавать предпочтение спецификаторам относительного пути в наборах правил для каждого каталога.
См. Также Как работает RewriteBase в .htaccess
Отключить,
MultiViews
если виртуальные пути перекрываютсяПерезапись URL-адресов в основном используется для поддержки виртуальных входящих путей. Обычно вы просто один диспетчерский скрипт (
index.php
) или несколько отдельных обработчиков (articles.php
,blog.php
,wiki.php
...). Последние могут конфликтовать с аналогичными виртуальными путями RewriteRule.Например, запрос
/article/123
может неявно сопоставлятьсяarticle.php
с/123
PATH_INFO. Тогда вам придется либо охранять свои правила с помощью обычногоRewriteCond
!-f
+!-d
, и / или отключить поддержку PATH_INFO, либо, возможно, просто отключитьOptions -MultiViews
.Это не значит, что вы всегда должны это делать . Content-Negotiation - это просто автоматизм для виртуальных ресурсов.
Заказ важен
См. Все, что вы когда-либо хотели знать о mod_rewrite, если вы еще этого не сделали. Объединение нескольких правил RewriteRules часто приводит к взаимодействию. Это не то, что обычно нужно предотвращать для каждого
[L]
флага, а схема, которую вы поймете, когда будете разбираться. Вы можете повторно повторно повторно записи виртуальных путей от одного правила к другому, пока не достигнет фактического целевого обработчика.Тем не менее, вы часто хотите иметь самые конкретные правила (фиксированные строковые
/forum/…
шаблоны или более ограничительные заполнители[^/.]+
) в ранних правилах. Общие правила slurp-all (.*
) лучше оставить последним . (Исключением являетсяRewriteCond -f/-d
защита в качестве основного блока.)Таблицы стилей и изображения перестают работать
Когда вы вводите структуры виртуальных каталогов,
/blog/article/123
это влияет на относительные ссылки на ресурсы в HTML (например,<img src=mouse.png>
). Что можно решить:href="https://stackoverflow.com/old.html"
илиsrc="/logo.png"
<base href="https://stackoverflow.com/index">
в свой HTML-<head>
раздел. Это неявно восстанавливает относительные ссылки к тому, что они были раньше.В качестве альтернативы вы можете создать дополнительные правила RewriteRules для повторной привязки
.css
или.png
пути к их исходным местоположениям. Но это и не нужно, или требует дополнительных перенаправлений и затрудняет кеширование.См. Также: CSS, JS и изображения не отображаются с красивым URL
RewriteConds просто маскирует одно RewriteRule
Распространенная ошибка заключается в том, что RewriteCond блокирует несколько RewriteRules (потому что они визуально расположены вместе):
По умолчанию это не так. Вы можете связать их, используя
[S=2]
флаг. В противном случае вам придется их повторить. Хотя иногда вы можете создать «перевернутое» первичное правило, чтобы [END] обработка перезаписи на раннем этапе.QUERY_STRING освобожден от правил RewriteRules
Вы не можете сопоставить
RewriteRule index.php\?x=y
, потому что mod_rewrite сравнивает только относительные пути по умолчанию. Однако вы можете сопоставить их по отдельности с помощью:См. Также Как сопоставить переменные строки запроса с mod_rewrite?
.htaccess
vs.<VirtualHost>
Если вы используете RewriteRules в файле конфигурации для каждого каталога, беспокоиться о производительности регулярного выражения бессмысленно. Apache сохраняет скомпилированные шаблоны PCRE дольше, чем процесс PHP с общей структурой маршрутизации. Однако для сайтов с высоким трафиком вам следует подумать о перемещении наборов правил в конфигурацию сервера vhost после того, как они будут протестированы в бою.
В этом случае предпочтите необязательный
^/?
префикс разделителя каталогов. Это позволяет свободно перемещать RewriteRules между PerDir и файлами конфигурации сервера.Когда что-то не работает
Не волнуйтесь.
Сравните
access.log
иerror.log
Часто вы можете понять, как работает RewriteRule, просто взглянув на ваши
error.log
иaccess.log
. Сопоставьте время доступа, чтобы увидеть, какой путь запроса был изначально введен и какой путь / файл Apache не смог разрешить (ошибка 404/500).Это не говорит вам, какой RewriteRule является виновником. Но недоступные финальные пути вроде
/docroot/21-.itle?index.php
могут выдать, где исследовать дальше. В противном случае отключите правила, пока не получите предсказуемый путь.Включите RewriteLog
См. Документацию Apache RewriteLog . Для отладки вы можете включить его в разделах vhost:
Это дает подробный обзор того, как пути входящих запросов изменяются каждым правилом:
Это помогает сузить слишком общие правила и ошибки регулярных выражений.
См. Также:
· .htaccess не работает (mod_rewrite)
· Советы по отладке правил перезаписи .htaccess
Прежде чем задать свой вопрос
Как вы, возможно, знаете, Stack Overflow очень подходит для того, чтобы задавать вопросы о mod_rewrite. Сделайте их по теме , включив предыдущие исследования и попытки (избегайте повторных ответов), продемонстрируйте основныерегулярное выражение понимание, и:
$_SERVER
среда PHP, если речь идет о несоответствии параметров.access.log
иerror.log
для проверки того, к чему привели существующие правила. А еще лучшеrewrite.log
резюме.Это позволяет получать более быстрые и точные ответы и делать их более полезными для других.
Прокомментируйте свой
.htaccess
Если вы откуда-то копируете примеры, позаботьтесь о том, чтобы добавить
# comment and origin link
. Не упоминать атрибуцию - это просто дурной манер, но зачастую это действительно вредит обслуживанию. Задокументируйте любой исходный код или учебник. В частности, будучи неопытным, вы должны быть тем более заинтересованы в том, чтобы не относиться к ним как к волшебным черным ящикам.Это не "SEO" -URL
Отказ от ответственности: просто раздражение. Вы часто слышите красивые схемы перезаписи URL, называемые ссылками "SEO" или что-то в этом роде. Хотя это полезно для примеров поиска в Google, это устаревшее неправильное употребление.
Ни один из современных поисковых систем не очень обеспокоены
.html
и.php
в сегментах пути или?id=123
строки запроса для этого вопроса. Старые поисковые системы, такие как AltaVista, действительно избегали сканирования веб-сайтов с потенциально неоднозначными путями доступа. Современные сканеры часто даже жаждут глубоких веб-ресурсов.По идее, «красивые» URL-адреса должны использоваться для того, чтобы сделать веб - сайты удобными для пользователей .
/common/tree/nesting
.Однако не жертвуйте уникальными требованиями ради конформизма.
инструменты
Существуют различные онлайн-инструменты для генерации RewriteRules для большинства URL-адресов с параметрами GET:
В основном просто выводит
[^/]+
общие заполнители, но, вероятно, этого достаточно для тривиальных сайтов.источник
Альтернативы mod_rewrite
Многие базовые схемы виртуальных URL-адресов могут быть реализованы без использования RewriteRules. Apache позволяет вызывать сценарии PHP без
.php
расширения и с виртуальнымPATH_INFO
аргументом.Используйте PATH_INFO , Люк
В настоящее время
AcceptPathInfo On
часто включен по умолчанию. Что в основном позволяет.php
URL-адресам и другим ресурсам нести виртуальный аргумент:Теперь это
/virtual/path
отображается в PHP, поскольку$_SERVER["PATH_INFO"]
вы можете обрабатывать любые дополнительные аргументы, как вам нравится.Это не так удобно , как имеющие Apache сегменты отдельный вход в путь
$1
,$2
,$3
и передачи их в качестве отдельных$_GET
переменных в РНР. Это просто имитация "красивых URL-адресов" с меньшими усилиями по настройке.Включите MultiViews, чтобы скрыть
.php
расширениеСамый простой способ также отказаться от
.php
«расширений файлов» в URL-адресах - это включить:Это позволяет Apache выбирать
article.php
HTTP-запросы/article
из-за совпадающего базового имени. И это хорошо работает вместе с вышеупомянутой функцией PATH_INFO. Таким образом, вы можете просто использовать такие URL-адреса, какhttp://example.com/article/virtual/title
. Это имеет смысл, если у вас есть традиционное веб-приложение с несколькими точками вызова / скриптами PHP.Обратите внимание, что у MultiViews есть другое / более широкое назначение. Это приводит к очень незначительному снижению производительности, потому что Apache всегда ищет другие файлы с соответствующими базовыми именами. Это фактически означало для Content-Переговоров , поэтому браузеры получают лучший вариант среди имеющихся ресурсов (например
article.en.php
,article.fr.php
,article.jp.mp4
).SetType или SetHandler для без расширений
.php
скриптов безБолее направленный подход, позволяющий избежать использования
.php
суффиксов в URL-адресах, - это настройка обработчика PHP для других файловых схем. Самый простой вариант - переопределить тип MIME / обработчика по умолчанию с помощью.htaccess
:Таким образом, вы можете просто переименовать свой
article.php
скрипт вarticle
(без расширения), но при этом он будет обрабатываться как PHP-скрипт.Теперь это может иметь некоторые последствия для безопасности и производительности, потому что все файлы без расширений теперь будут передаваться через PHP. Поэтому вы можете также установить это поведение только для отдельных файлов:
Это в некоторой степени зависит от настроек вашего сервера и используемого PHP SAPI. Общие альтернативы включают
ForceType application/x-httpd-php
илиAddHandler php5-script
.Другие схемы переписывания Apache
Среди множества опций Apache предоставляет
mod_alias
функции, которые иногда работают так же хорошо, какmod_rewrite
RewriteRules. Обратите внимание, что большинство из них необходимо настраивать в<VirtualHost>
разделе, а не в.htaccess
файлах конфигурации для каждого каталога .ScriptAliasMatch
предназначен в первую очередь для сценариев CGI, но также должен работать и для PHP. Он позволяет использовать регулярные выражения, как и любые другиеRewriteRule
. Фактически, это, пожалуй, самый надежный вариант настройки универсального переднего контроллера.И простой
Alias
помогает также с несколькими простыми схемами перезаписи.Даже простая
ErrorDocument
директива может использоваться, чтобы позволить скрипту PHP обрабатывать виртуальные пути. Обратите внимание, что это сложный обходной путь, однако он запрещает все, кроме запросов GET, и по определению заполняет журнал error.log.См. Http://httpd.apache.org/docs/2.2/urlmapping.html для получения дополнительных советов.
источник