Ответ 1
Флаг [L]
действительно означает "последний", но применим только к правилам текущей области. Из вашего вопроса это применимо только к правилам в файле htaccess. Если в подкаталоге есть правила, любые правила в родительском каталоге выкидываются из окна. Они не применяются вообще, если вы не используете директиву RewriteOptions Inherit
(которая добавит к концу правил какие-либо правила из родительского файла htaccess).
Учитывая ваш пример:
root.com/subdirectory1/subdirectory2
^ ^ ^
| | |
A B C
Если есть файлы htaccess в A, B и C и переписывать правила во всех 3, если запрашивается http://root.com
(ваш каталог "root.com" ), применяются только правила в A. Если кто-то запрашивает http://root.com/subdirectory1
, тогда применяются только правила из B, и любые правила в игнорируются (без опции Inherit
). Аналогично, если кто-то отправляется на http://root.com/subdirectory1/subdirectory2
, тогда применяются только правила в C, если нет вариантов наследования.
Флаг [L]
не имеет никакого воспроизведения ни в одном из них, так как область действия здесь находится только в правилах файла htaccess. Также обратите внимание, что [L]
не обязательно означает "прекратить переписывание ЗДЕСЬ", так как механизм перезаписи будет зацикливаться до тех пор, пока URI, идущий в двигатель, не перестанет меняться. [L]
просто означает прекратить переписывание в текущей итерации цикла перезаписывания.
Немного больше о деталях цикла:
В процессе обработки URL-адресов apache пытается сопоставить URL-адрес файла или ресурса. Множество различных модулей могут участвовать в конвейере обработки, например mod_rewrite или mod_proxy или mod_alias. В любой момент этот URI может быть изменен, помечен как перенаправленный, помечен как проксированный, помечен для выброса ошибки и т.д. Когда URI получает mod_rewrite, механизм перезаписи собирает кучу правил из конфигурации vhost и соответствующий файл htaccess; обратите внимание, здесь есть 2 разных области. Каждая область правил применяется к URI, и если ни одно из правил не соответствует, то mod_rewrite выполняется. Если одно из правил соответствует, есть внутренняя переадресация, то есть URI изменяется, а затем перенаправляется обратно в конвейер обработки и mod_rewrite. Таким образом, тот же диапазон правил снова применяется, и если одно из правил соответствует и применяется, то снова происходит повторение цикла правил. Там есть директива, которую вы можете установить в конфигурации vhost/server под названием LimitInternalRecursion
, которая устанавливает предел этих внутренних переадресаций. Если количество циклов перезаписи (то есть перенаправление обратно к себе) превышает этот предел (по умолчанию это 10, я думаю), то вы получите ошибку внутреннего сервера 500.
Это может показаться странным, но есть много примеров для этого. Пример: удалить все _
из URI и заменить на -
:
RewriteRule ^(.*)_(.*)$ /$1-$2 [L]
Если URI равен /a_b_c_d_foo
, то в первый раз URI будет изменен на /a_b_c_d-foo
, затем он будет циклически изменен на `/a_b_c-d-foo
, затем снова /a_b-c-d-foo
и к 5-му разму времени вы получите /a-b-c-d-foo
. Он будет зацикливаться еще раз, но поскольку шаблон ^(.*)_(.*)$
не совпадает, URI проходит через механизм перезаписи и останавливается цикл.
Проблема возникает, когда люди создают правила, которые не учитывают цикл, например: rewrite /<anything>
to /foo/<anything>
:
RewriteRule ^(.*)$ /foo/$1 [L]
Если URI /bar
, то при первом переходе URI на /foo/bar
, и это желаемый результат. Но URI получает внутреннюю перенаправленную обратно в механизм перезаписи и повторяет одно и то же правило: /foo/foo/bar
, затем снова: /foo/foo/foo/bar
и снова: /foo/foo/foo/foo/bar
, пока не будет достигнут внутренний предел рекурсии, и вы получите ошибка сервера 500.