是否可以通过PHP访问REQUEST_FILENAME?

时间:2013-04-10 18:09:15

标签: php .htaccess mod-rewrite

我正在尝试更详细地了解以下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查看它的值吗?

1 个答案:

答案 0 :(得分:5)

来自RewriteCond

  

<强> REQUEST_FILENAME
  与请求匹配的文件或脚本的完整本地文件系统路径(如果在引用REQUEST_FILENAME时服务器已确定)。否则,例如在虚拟主机上下文中使用时,其值与REQUEST_URI相同。根据AcceptPathInfo的值,服务器可能只使用REQUEST_URI的某些主要组件将请求映射到文件。

$_SERVER

  

'SCRIPT_FILENAME'
      当前正在执行的脚本的绝对路径名。

如果REQUEST_URI实际上对应于现有文件,则这将是相同的(脚本的完整路径)。

如果没有,REQUEST_FILENAME将只是REQUEST_URISCRIPT_FILENAME将是执行的PHP脚本的名称。 $_SERVER['REQUEST_URI']REQUEST_FILENAME(又名REQUEST_URI)。

在您的情况下,SCRIPT_FILENAME始终为/path/to/index.phpREQUEST_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']访问它。

相关问题