我正在尝试更详细地了解以下htaccess规则:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/(favicon\.ico|apple-touch-icon.*\.png)$ [NC]
RewriteRule (.+) index.php?p=$1 [QSA,L]
</IfModule>
具体来说,我试图了解REQUEST_FILENAME的工作原理。我发现有几个资源可以讨论这个,从mod_rewrite docs到Stack Overflow上的答案。但似乎没有人正在解决我正在寻找的问题,我如何仔细查看REQUEST_FILENAME变量才能看到它的值?
通常,当我想查看.htaccess中引用的变量时,我将使用print_r查看$ _SERVER全局,以查看这些值的服务器内容:
echo "<pre>";
print_r($_SERVER);
echo "</pre>";
die('fin');
这可以帮助我看到上面的$ _SERVER ['REQUEST_URI']等值。但似乎REQUEST_FILENAME在我当前环境中的任何PHP $ GLOBALS中都不可用。我确实看到了SCRIPT_FILENAME的值,有几个消息来源说这两个值是相等的,但不清楚它们是否是替代品,或者如果第一个不存在则REQUEST_FILENAME会回退到SCRIPT_FILENAME。
我能够通过稍微更新htaccess规则来输出REQUEST_FILENAME值,以输出URL中的值,将最后一行更改为:
RewriteRule (.+) index.php?p=%{REQUEST_FILENAME} [R=302,QSA,L]
但是为什么这个值在PHP的任何地方都不可用?有什么我忽略的可以帮助我理解这个变量的存储位置以及如何通过PHP查看它的值吗?
答案 0 :(得分:5)
<强> REQUEST_FILENAME 强>
与请求匹配的文件或脚本的完整本地文件系统路径(如果在引用REQUEST_FILENAME时服务器已确定)。否则,例如在虚拟主机上下文中使用时,其值与REQUEST_URI相同。根据AcceptPathInfo的值,服务器可能只使用REQUEST_URI的某些主要组件将请求映射到文件。
'SCRIPT_FILENAME'
当前正在执行的脚本的绝对路径名。
如果REQUEST_URI
实际上对应于现有文件,则这将是相同的(脚本的完整路径)。
如果没有,REQUEST_FILENAME
将只是REQUEST_URI
而SCRIPT_FILENAME
将是执行的PHP脚本的名称。 $_SERVER['REQUEST_URI']
将REQUEST_FILENAME
(又名REQUEST_URI
)。
在您的情况下,SCRIPT_FILENAME
始终为/path/to/index.php
,REQUEST_FILENAME
/ REQUEST_URI
可通过$_SERVER['REQUEST_URI']
访问。
<强>更新强>:
REQUEST_URI
永远不会是文件名,因为它缺少文档根前缀。当你使用
RewriteCond %{REQUEST_URI} !-f
即使请求的URL与现有文件匹配,条件也始终为真。以下RewriteRule
将始终执行,但它应调用另一个PHP脚本或提供HTML,CSS或图像文件。
<强>更新强>:
要真正回答这个问题。
但为什么这个值在PHP的任何地方都不可用?
REQUEST_FILENAME
在PHP中不可用,因为它不在环境中或请求的标题中。
您在PHP中可以看到的是一些环境变量或标题或PHP可以推断自己的东西。由于PHP没有尝试或无法在请求URI和某些文件名之间建立连接,因此无法在任何地方访问它。毕竟,REQUEST_FILENAME
可能位于文件系统的任何位置。
但是,您可以自己将其置于环境中
RewriteRule (.+) index.php?p=$1 [QSA,L,E=REQUEST_FILENAME:%{REQUEST_FILENAME}]
并以PHP $_SERVER['REDIRECT_REQUEST_FILENAME']
访问它。