【问题标题】:Is it possible to access REQUEST_FILENAME via PHP? [duplicate]是否可以通过 PHP 访问 REQUEST_FILENAME? [复制]
【发布时间】:2013-04-02 17:30:55
【问题描述】:

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

【问题讨论】:

  • 谢谢马克。我想我处理问题的方式有点不同,但这个答案也有帮助。我发现有关 PHP 设置的讨论很有帮助。
  • +1 表示重新打开。报告的重复是关于REQUEST_URI,而这个问题涉及REQUEST_FILENAME,这是一个完全不同的野兽。
  • 不管怎样,我最初的搜索是专门针对 REQUEST_FILENAME 的,对于具有设计背景的人来说,它的行为并不明显。虽然更有经验的 Apache 或 Web 服务器的人可能能够在这两个问题之间建立联系,但这对我来说并不明显,Olaf 的回答确实帮助我从我接近它的方向理解它.

标签: php .htaccess mod-rewrite


【解决方案1】:

来自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.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'] 访问它。

【讨论】:

  • 谢谢奥拉夫。你的回答帮助我理解了。那么为什么这个 htaccess 规则使用 REQUEST_FILENAME 而不是对所有内容都使用 REQUEST_URI 呢?如果我更新规则以使用 REQUEST_URI 代替 REQUEST_FILENAME 它会出错,所以似乎 REQUEST_URI 不能用于测试文件或目录,即使值相同并且它们都是 RewriteCond 指令的一部分。
猜你喜欢
  • 2019-06-11
  • 2018-06-08
  • 2013-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-17
  • 1970-01-01
相关资源
最近更新 更多