是否可以通过PHP访问REQUEST_FILENAME


Is it possible to access REQUEST_FILENAME via PHP?

我正在尝试更详细地理解以下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_URISCRIPT_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中进行访问。