我正在尝试更详细地理解以下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文档到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规则来输出URL中的值,将最后一行更改为:来输出REQUEST_FILENAME值
RewriteRule (.+) index.php?p=%{REQUEST_FILENAME} [R=302,QSA,L]
但是为什么这个值在PHP中的任何地方都不可用呢?有没有什么我忽略的东西可以帮助我了解这个变量存储在哪里,以及如何通过PHP查看它的值?
来自RewriteCond
REQUEST_FILENAME
与请求匹配的文件或脚本的完整本地文件系统路径(如果服务器在引用request_FILENAME时已经确定(。否则,例如在虚拟主机上下文中使用时,将使用与REQUEST_URI相同的值。根据AcceptPathInfo的值,服务器可能只使用了REQUEST_URI的一些主要组件来将请求映射到文件。
和来自$_SERVER
'CRIPT_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与现有文件匹配,条件也将始终为true。以下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}]
并以CCD_ 19的形式在PHP中进行访问。