оценивает ли mod_rewrite {REQUEST_FILENAME} после каждого правила перезаписи?

#apache #mod-rewrite

#apache #mod-перезапись

Вопрос:

Вот случай :

 RewriteEngine On
RewriteBase /app/webroot/

RewriteRule ^(.*)$ $1 [QSA]

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
  

Использует ли RewriteConds для второго правила результат первого RewriteRule ?

Например, если я запрашиваю /onestaticfile.txt , и этот файл действительно существует в /app/webroot, как быть уверенным, что конечный URL-адрес будет /app/webroot/onestaticfile.txt вместо /app/webroot/index.php?url=onestaticfile.txt ?

Комментарии:

1. В Virtualhost (не в .htaccess) добавьте RewriteEngine On , RewriteLogLevel 9 , RewriteLog /path/to/a/rewrite.log и посмотрите, что произойдет.

2. В Apache 2.4 что-то вроде LogLevel warn rewrite:trace8 . RewriteLogLevel удалено.

Ответ №1:

Например, если я запрашиваю /onestaticfile.txt , и этот файл действительно существует в /app/webroot, как быть уверенным, что конечный URL-адрес будет /app/webroot/onestaticfile.txt вместо /app/webroot/index.php?url=onestaticfile.txt ?

Будут оценены секунды перезаписи для второго правила. Но поскольку onestaticfile.txt существует, он не выполнит!-f-тест, и второе правило не будет применено (поэтому окончательный URL будет: /app/webroot/onestaticfile.txt ). Аналогично, если onestaticfile.txt не существует, будет применено 2-е правило.

В любом случае, когда применяется правило, происходит внутреннее перенаправление, и все повторяется с перезаписанным URI. Но 2-й раз не изменяет базовый URI (без строк запроса), поэтому во второй раз ничего не происходит.

Если бы у вас была буква L в квадратных скобках вашего первого правила, 2-е правило никогда не было бы применено, потому что перезапись всегда будет заканчиваться на первом правиле.