Я не вижу сообщений, в которых обсуждаются различия между REQUEST_URI
и REQUEST_FILENAME
, хотя я вижу во многих сообщениях они используются взаимозаменяемо.
Я включил журнал mod_rewrite
( LogLevel alert rewrite: trace8
), заменил REQUEST_FILENAME
на REQUEST_FILENAME
REQUEST_FILEN ], просмотрел журнал перезаписи в каждой конфигурации, и процесс перезаписи точно такой же.
Итак, мой вопрос: :
Они одинаковы в 99% случаев?
Я не сказал 100% потому что я вижу в документе ( https://httpd.apache.org/docs/current/mod/mod_rewrite.html ) упоминание об исключении для REQUEST_URI
, относящемся к так называемому AcceptPathInfo
.
REQUEST_FILENAME
Полный путь локальной файловой системы к файлу или сценарию. соответствие запросу, если это уже было определено сервер во время ссылки
REQUEST_FILENAME
. В противном случае, например, при использовании в контексте виртуального хоста то же значение, что иREQUEST_URI
. В зависимости от значенияAcceptPathInfo
сервер может иметь только использовали некоторые ведущие компонентыREQUEST_URI
для сопоставления запроса с файл.
На самом деле мне трудно понять все определение, а не только последнее предложение.
Я использую REQUEST_FILENAME
и REQUEST_URI
в основном между
.
Мой
настройки:
<VirtualHost *:443>
ServerAdmin admin@exmaple.com
DocumentRoot /var/www/example.com/public_html
ServerName example.com
ServerAlias www.example.com
LogLevel alert rewrite:trace8
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
RewriteEngine On
#RewriteCond %{REQUEST_URI} !-f
#RewriteCond %{REQUEST_FILENAME} !-d
#RewriteRule (.*) /tq_info.php?p=%{REQUSET_URI}
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !/.*\.php$
RewriteCond %{REQUEST_FILENAME} !/admin/.*
RewriteRule (.*) /index.php/$1 [L]
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
</VirtualHost>
Они очень разные и служат разным целям.
REQUEST_URI — это компонент пути URI в запросе. Например, /tq_info.php
.
REQUEST_FILENAME является результатом попытки найти файл в локальной файловой системе путем применения пути URI к корню документа или любого псевдонима, который мог быть определен. Таким образом, если файл существует, для него будет установлено значение /var/www/example.com/public_html/tq_info.php
. Он используется для поиска файла в файловой системе. Он устанавливается равным REQUEST_URI только в том случае, если в файловой системе нет файла. В этом случае запрос будет передан обработчику 404 или вышестоящему веб-приложению, если вы определили его в конфигурации своего веб-сервера, которое соответствует пути URI.
Когда вы выбираете, какой из них использовать, вам нужно подумать о том, пытаетесь ли вы работать с компонентом пути URI или с путем соответствующего файла в вашей файловой системе.
Я опаздываю на вечеринку, но кое-что проясню:
REQUEST_URI
, как Майкл Хэмптон написал, всегда содержит компонент пути запрошенного URI. Это означает, что параметры запроса (например, ?a=b
) удаляются из URI запроса.
REQUEST_FILENAME
— зверь.
В лучшем случае он будет содержать сопоставление пути локальной файловой системы с тем, что было запрошено, и это будет точно %{DOCUMENT_ROOT}%{REQUEST_URI}
. Однако это не обязательно. Если %{REQUEST_URI}
сопоставляется с псевдонимом, он будет прозрачно перенаправлен, поэтому %{REQUEST_FILENAME}
тоже будет другим. Это также верно для цепочки перенаправлений, например /
➜ /tricked/you
, причем последний путь действительно существует (относительно корня документа). Можно возразить, что это промежуточный шаг, который можно игнорировать, но цепочка возможна.
Затем параметр конфигурации AcceptPathInfo
изменяет способ сопоставления URI запросов с файлами. Если установлено значение на
, сервер также сканирует файлы на наличие вложенных путей и предоставляет конечные данные в %{PATH_INFO}
. В таком случае только часть %{REQUEST_URI}
может использоваться для сопоставления пути к расположению в файловой системе. Расширяя приведенный выше пример, если /tricked/you
ссылается на правильный файл, %{REQUEST_URI}
из /tricked/you/and/then/some/more
позволит httpd сопоставить запрос с тем, что /tricked/you
сопоставили бы и выставит /and/then/some/more
как %{PATH_INFO}
, что означает, что %{REQUEST_FILENAME}
в конечном итоге будет чем-то вроде %{DOCUMENT_ROOT}/tricked/you
.
Наконец, от контекста файла %{REQUEST_FILENAME}
уже расширен до фактического пути к файловой системе или все еще установлено значение %{REQUEST_URI}
. его использование. В контексте VirtualHost
, который вы используете, это никогда не будет сопоставленным путем файловой системы — главным образом потому, что эта кодовая точка находится перед фактической точкой сопоставления в пути кода. К сожалению, нет простого способа узнать, мог ли httpd уже сопоставить (часть) %{REQUEST_URI}
с местоположением в файловой системе или нет, кроме просмотра исходного кода и надежды, что выполнение путь не изменится неожиданно.
Однако есть несколько предположений, которые вы можете сделать с уверенностью:
Контексты VirtualHost
будут видеть только несопоставленные значения Все остальное методом проб и ошибок. В частности, %{REQUEST_FILENAME}
не нужно отображать в любом случайно выполняемом сценарии. Подумайте об обертках, которые фактически определяют, какой файл обслуживать или выполнять, когда он установлен в качестве обработчиков.