PHP的$_SERVER数组中存在五个和路径相关的变量:PHP_SELF
,SCRIPT_NAME
,
SCRIPT_FILENAME
,PATH_INFO
,REQUEST_URI
,这五个变量经常会被混淆,做下区分。
Nginx0.8.54 + FastCGI + PHP5.3.4
要先配置Nginx的PATH_INFO
,在nginx.conf
中加入如下配置:
location ~ .* .php {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
#从$fastcgi_script_name中分离出真正执行的脚本名称和PATH_INFO
set $real_script_name $fastcgi_script_name;
if ($fastcgi_script_name ~ "^(.+?.php)(/.+)$") {
set $real_script_name $1;
set $path_info $2;
}
#重新设置SCRIPT_FILENAME
fastcgi_param SCRIPT_FILENAME $document_root$real_script_name;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
#重新设置SCRIPT_NAME
fastcgi_param SCRIPT_NAME $real_script_name;
fastcgi_param PATH_INFO $path_info;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param REDIRECT_STATUS 200;
}
我们的根目录为/var/www
,测试域名为example.com
(不过这个域名只能改hosts
文件YY一下了),结构如下:
var
|---www
|---test
|---test.php
使用如下脚本进行测试:
<?php
echo 'SCRIPT_NAME=' . $_SERVER['SCRIPT_NAME'] . '<br />';
echo 'SCRIPT_FILENAME=' . $_SERVER['SCRIPT_FILENAME'] . '<br />';
echo 'PATH_INFO=' . $_SERVER['PATH_INFO'] . '<br />';
echo 'REQUEST_URI=' . $_SERVER['REQUEST_URI'] . '<br />';
?>
PHP_SELF: 当前所执行的脚本的文件名,这个值是相对于根目录来说。
如果请求http://example.com/test/test.php?k=v,则PHP_SELF
的值为
/test/test.php。
SCRIPT_NAME: 当前执行的脚本的路径。
如果请求http://example.com/test/test.php?k=v,则SCRIPT_NAME
的值
为/test/test.php。这个变量是在CGI/1.1中定义的。
SCRIPT_FILENAME: 当前执行的脚本的绝对路径。
如果请求http://example.com/test/test.php?k=v,则SCRIPT_FILENAME
的值
为/var/www/test/test.php。
注意:如果一个脚本以相对路径,CLI方式来执行,例如../test/test.php,那么
$_SERVER['SCRIPT_FILENAME']
的值为相对路径,即../test/test.php。
PATH_INFO:客户端提供的路径信息,即在实际执行脚本后面尾随的内容,但是会去掉Query String。
如果请求http://example.com/test/test.php/a/b?k=v,则PATH_INFO
的值为/a/b。
CGI1.1标准中如下描述:"The PATH_INFO string is the trailing part of thecomponent of the script URI that follows the SCRIPT_NAME part of the path."
REQUEST_URI:包含HTTP协议中定义的URI内容。
如果请求http://example.com/test/test.php?k=v,则REQUEST_URI
为/test/test.php?k=v
PHP_SELF VS SCRIPT_NAME:
PHP_SELF
和SCRIPT_NAME
的值在大部分情况下都是一样的,但是访问
http://example.com/test/test.php/a/b?k=v这类URL时候,PHP_SELF
为/test/test.php/a/b,SCRIPT_NAME
为/test/test.php,可以看出PHP_SELF
比SCRIPT_NAME
多了PATH_INFO
的内容。
REQUEST_URI VS SCRIPT_NAME:
在访问http://example.com/test/test.php?k=v后,REQUEST_URI
为/test/test.php?k=v,SCRIPT_NAME
为/test/test.php,可以看出REQUEST_URI
比SCRIPT_NAME
多了Query String。
如果http://example.com/test/test.php在服务器端做了rewrite:
rewrite /test/test.php /test/test2.php;
那么REQUEST_URI
为/test/test.php,SCRIPT_NAME
为/test/test2.php。