您好,我对PHP关于无扩展PHP文件的预期/默认行为以及/或“过去”(我想要)处理请求的实际文件的URL请求感到困惑(即,PHP的默认“回退” “在采取行动之前采取行动完全404-ing”。这是我的情况:
我的本地服务器上的目录结构(使用非常基本的PHP 5.5.1设置运行nginx 1.5.3)如下所示:
/index
/index.php
/other
/other.php
/rootdir/index
/rootdir/index.php
/rootdir/other
/rootdir/other.php
所有八个文件的内容都是相同的:
<?php
echo $_SERVER['PHP_SELF'] . ', ' . $_SERVER['REQUEST_URI'];
?>
但是,点击相应的端点会产生一些奇怪的(对我而言)结果。
GET /index.php
'/index.php, /index.php' # Makes sense...
GET /index.php/something_else
'/index.php, /index.php/something_else' # Also makes sense...
GET /index/something_else
'/index.php, /index/something_else' # Let's call this ANOMALY 1... (see below)
GET /something_else
'/index.php, /something_else' # ANOMALY 2
GET /other.php
'/other.php, /other.php' # Expected...
GET /other.php/something_else
'/index.php, /other.php/something_else' # ANOMALY 3
GET /rootdir/index.php
'/rootdir/index.php, /rootdir/index.php' # Expected...
GET /rootdir/index.php/something_else
'/index.php, /rootdir/index.php/something_else' # ANOMALY 4
GET /rootdir/other.php
'/rootdir/other.php, /rootdir/other.php' # Expected...
GET /rootdir/other.php/something_else
'/index.php, /rootdir/other.php/something_else' # ANOMALY 5
我的理解是当服务器无法在请求URI中找到用户正在查找的内容时,服务器会重定向到/index.php
;那很有意义...... 我不明白是:
/index.php
;我想要< / em>它显示一个合法的,非自定义的404页面,如果找不到和/或无法处理。我认为它应该显示默认服务器404页面,当它找不到的东西......显然情况并非总是如此......?)/rootdir/index.php
子目录中找不到内容时不会尝试/rootdir/
。对于未找到的地址,是否有人能够阐明PHP的逻辑是什么(或者可能是nginx正在做的事情;我还未能解决这个问题)?为什么我看到我所看到的? (特别是关于异常#4和#5。我希望它使用/rootdir/index.php
来处理它的“404”, 或 我期待一个真正的404页面; /index.php
的回退是出乎意料的。)
作为直接推论(corollical?)的问题,如何模拟无扩展的PHP文件来处理“低于”它们的命中(例如在Anomaly#1案例中) ;这实际上正是我想要的,虽然它不是我想象的那样 没有 依赖.htaccess
,mod_rewriting或重定向?或者这是一个愚蠢的问题? : - )
我正在尝试推出一个自定义实现来处理/some_dir/index.php/fake_subdir
和/some_other_dir/index.php/fake_subdir
等请求(即不同的“回退处理程序”),而不依赖于Apache,但是PHP(或nginx)背后的逻辑?)默认回退行为是逃避我。这些页面主要来自这个问题:
答案 0 :(得分:1)
GET /other.php/something_else
这在Apache中称为PATH_INFO
。当Apache扫描URL的“目录”时,它将返回第一个文件(或执行第一个脚本),实际上是文件/脚本,例如。
GET /foo/bar/baz/index.php/a/b/c/
^--dir
^--dir
^---dir
^---script
^^^^^^^--- path_info
实际上,真正的要求是
GET /foo/bar/baz/index.php
然后Apache将获取URL的目录结构的未使用的尾部,并将其转换为路径信息。在PHP中,你将有
$_SERVER['REQUEST_URI'] = '/foo/bar/baz/index.php';
$_SERVER['PATH_INFO'] = 'a/b/c';
答案 1 :(得分:0)
好吧,我弄清楚发生了什么:我的配置错误的nginx服务器。
Marc B的回答虽然与Apache有关,但却促使我查看了我的PATH_INFO值 - 看, PATH_INFO不存在,,即使对GET /other.php/something_else
这样的请求也是如此。
更多的搜索结果显示了答案。使用nginx的fastcgi_split_path_info
将URI拆分为a)脚本的路径和b)脚本名称后面显示的路径失败如果在之后 使用try_files
指令,因为它重写URI 指向磁盘上的文件。这消除了获取PATH_INFO字符串的任何可能性。
作为一个解决方案,我做了三件事(其中一些可能是多余的,但我做了所有这些,以防万一):
在服务器的位置区块中,在 之前使用fastcgi_split_path_info
fastcgi_param PATH_INFO $fastcgi_path_info;
...并在 之前
将try_files
存储为本地变量,以防以后更改(例如使用$fastcgi_path_info
)
使用set $path_info $fastcgi_path_info;
时,不使用try_files
...使用$uri
。 (很确定这是我最大的错误。)
$fastcgi_script_name
server {
# ... *snip* ...
location ~ \.php {
# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_index index.php;
fastcgi_intercept_errors on;
fastcgi_pass 127.0.0.1:9000;
try_files $fastcgi_script_name =404;
}
# ... *snip* ...
}
包含的位置:
fastcgi_params
以下链接可以很好地解释问题并提供备用nginx配置: