php PHP_SELF vs PATH_INFO vs SCRIPT_NAME vs REQUEST_URI
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/279966/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
PHP_SELF vs PATH_INFO vs SCRIPT_NAME vs REQUEST_URI
提问by Eli
I am building a PHP application in CodeIgniter. CodeIgniter sends all requests to the main controller: index.php. However, I don't like to see index.phpin the URI. For example, http://www.example.com/faq/whateverwill route to http://www.example.com/index.php/faq/whatever. I need a reliable way for a script to know what it's address is, so it will know what to do with the navigation. I've used mod_rewrite, as per CodeIgniter documentation.
我正在 CodeIgniter 中构建一个 PHP 应用程序。笨发送到主控制器的所有请求:index.php。但是,我不喜欢index.php在 URI 中看到。例如,http://www.example.com/faq/whatever将路由到http://www.example.com/index.php/faq/whatever. 我需要一种可靠的方式让脚本知道它的地址是什么,这样它就会知道如何处理导航。mod_rewrite根据 CodeIgniter 文档,我使用过。
The rule is as follows:
规则如下:
RewriteEngine on
RewriteCond !^(images|inc|favicon\.ico|index\.php|robots\.txt)
RewriteRule ^(.*)$ /index.php/ [L]
Normally, I would just check php_self, but in this case it's always index.php. I can get it from REQUEST_URI, PATH_INFO, etc., but I'm trying to decide which will be most reliable. Does anyone know (or know where to find) the real difference between PHP_SELF, PATH_INFO, SCRIPT_NAME, and REQUEST_URI? Thanks for your help!
通常,我只会检查php_self,但在这种情况下它总是index.php。我可以从REQUEST_URI、PATH_INFO等获取它,但我正在尝试确定哪个最可靠。没有人知道(或不知道在哪里可以找到)之间的真正区别PHP_SELF,PATH_INFO,SCRIPT_NAME,和REQUEST_URI?谢谢你的帮助!
Note: I've had to add spaces, as SO sees the underscore, and makes it italic for some reason.
注意:我不得不添加空格,因为 SO 看到下划线,并且出于某种原因将其设为斜体。
Updated: Fixed the spaces.
更新:修正了空格。
采纳答案by Jeremy Ruten
The PHP documentationcan tell you the difference:
该PHP文件可以告诉你的区别:
'PHP_SELF'
The filename of the currently executing script, relative to the document root. For instance, $_SERVER['PHP_SELF']in a script at the address http://example.com/test.php/foo.barwould be /test.php/foo.bar. The __FILE__constant contains the full path and filename of the current (i.e. included) file. If PHP is running as a command-line processor this variable contains the script name since PHP 4.3.0. Previously it was not available.
'SCRIPT_NAME'
Contains the current script's path. This is useful for pages which need to point to themselves. The __FILE__constant contains the full path and filename of the current (i.e. included) file.
'REQUEST_URI'
The URI which was given in order to access this page; for instance, '/index.html'.
'PHP_SELF'
当前正在执行的脚本的文件名,相对于文档根目录。例如,地址为http://example.com/test.php/foo.bar的脚本中的$_SERVER['PHP_SELF']将是/test.php/foo.bar。该__FILE__常量包含当前的完整路径和文件名(例如包含文件)。如果 PHP 作为命令行处理器运行,则此变量包含自 PHP 4.3.0 以来的脚本名称。以前它不可用。
'SCRIPT_NAME'
包含当前脚本的路径。这对于需要指向自身的页面很有用。该__FILE__常量包含当前的完整路径和文件名(例如包含文件)。
'REQUEST_URI'
为访问此页面而提供的 URI;例如,'/index.html'。
PATH_INFO doesn't seem to be documented...
PATH_INFO 似乎没有记录...
回答by Odin
Some practical examples of the differences between these variables:
Example 1.
PHP_SELF is different from SCRIPT_NAME onlywhen requested url is in form:
http://example.com/test.php/foo/bar
这些变量之间差异的一些实际示例:
示例 1. PHP_SELF 与 SCRIPT_NAME仅当请求的 url 为以下形式时才不同:http:
//example.com/test.php/foo/bar
[PHP_SELF] => /test.php/foo/bar
[SCRIPT_NAME] => /test.php
(this seems to be the only case when PATH_INFO contains sensible information [PATH_INFO] => /foo/bar) Note: this used to be different in some older PHP versions (<= 5.0 ?).
(这似乎是 PATH_INFO 包含合理信息 [PATH_INFO] => /foo/bar 的唯一情况) 注意:这在某些较旧的 PHP 版本(<= 5.0 ?)中曾经有所不同。
Example 2.
REQUEST_URI is different from SCRIPT_NAME when a non-empty query string is entered:
http://example.com/test.php?foo=bar
示例 2. 输入非空查询字符串时,REQUEST_URI 与 SCRIPT_NAME 不同:http:
//example.com/test.php?foo=bar
[SCRIPT_NAME] => /test.php
[REQUEST_URI] => /test.php?foo=bar
Example 3. REQUEST_URI is different from SCRIPT_NAME when server-side redirecton is in effect (for example mod_rewrite on apache):
示例 3. 服务器端重定向生效时,REQUEST_URI 与 SCRIPT_NAME 不同(例如 apache 上的 mod_rewrite):
[REQUEST_URI] => /test.php
[SCRIPT_NAME] => /test2.php
Example 4.
REQUEST_URI is different from SCRIPT_NAME when handling HTTP errors with scripts.
Using apache directive ErrorDocument 404 /404error.php
http://example.com/test.php
示例 4. 使用脚本处理 HTTP 错误时,REQUEST_URI 与 SCRIPT_NAME 不同。
使用 apache 指令 ErrorDocument 404 /404error.php
http://example.com/test.php
[REQUEST_URI] => /test.php
[SCRIPT_NAME] => /404error.php
On IIS server using custom error pages
http://example.com/test.php
在 IIS 服务器上使用自定义错误页面
http://example.com/test.php
[SCRIPT_NAME] => /404error.php
[REQUEST_URI] => /404error.php?404;http://example.com/test.php
回答by Mike
PATH_INFOis only available when using htaccess like this:
PATH_INFO仅在像这样使用 htaccess 时可用:
Example 1
示例 1
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^(favicon\.ico|robots\.txt)
RewriteRule ^(.*)$ index.php/ [L]
Remains the same
保持原样
[SCRIPT_NAME] => /index.php
Root
根
[PHP_SELF] => /index.php
[PATH_INFO] IS NOT AVAILABLE (fallback to REQUEST_URI in your script)
[REQUEST_URI] => /
[QUERY_STRING] =>
Path
小路
[PHP_SELF] => /index.php/test
[PATH_INFO] => /test
[REQUEST_URI] => /test
[QUERY_STRING] =>
Query String
请求参数
[PHP_SELF] => /index.php/test
[PATH_INFO] => /test
[REQUEST_URI] => /test?123
[QUERY_STRING] => 123
Example 2
示例 2
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^(favicon\.ico|robots\.txt)
RewriteRule ^(.*)$ index.php?url= [L,QSA]
Remains the same
保持原样
[SCRIPT_NAME] => /index.php
[PHP_SELF] => /index.php
[PATH_INFO] IS NOT AVAILABLE (fallback to REQUEST_URI in your script)
Root
根
[REQUEST_URI] => /
[QUERY_STRING] =>
Path
小路
[REQUEST_URI] => /test
[QUERY_STRING] => url=test
Query String
请求参数
[REQUEST_URI] => /test?123
[QUERY_STRING] => url=test&123
Example 3
示例 3
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^(favicon\.ico|robots\.txt)
RewriteRule ^(([a-z]{2})|(([a-z]{2})/)?(.*))$ index.php/ [NC,L,E=LANGUAGE:]
or
或者
RewriteRule ^([a-z]{2})(/(.*))?$ [NC,L,E=LANGUAGE:]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^(favicon\.ico|robots\.txt)
RewriteRule ^(.*)$ index.php/ [L]
Remains the same
保持原样
[SCRIPT_NAME] => /index.php
Root
根
[PHP_SELF] => /index.php
[PATH_INFO] IS NOT AVAILABLE (fallback to REQUEST_URI in your script)
[REQUEST_URI] => /
[QUERY_STRING] =>
[REDIRECT_LANGUAGE] IS NOT AVAILABLE
Path
小路
[PHP_SELF] => /index.php/test
[PATH_INFO] => /test
[REQUEST_URI] => /test
[QUERY_STRING] =>
[REDIRECT_LANGUAGE] =>
Language
语
[PHP_SELF] => /index.php/
[PATH_INFO] => /
[REQUEST_URI] => /en
[QUERY_STRING] =>
[REDIRECT_LANGUAGE] => en
Language path
语言路径
[PHP_SELF] => /index.php/test
[PATH_INFO] => /test
[REQUEST_URI] => /en/test
[REDIRECT_LANGUAGE] => en
Language Query string
语言查询字符串
[PHP_SELF] => /index.php/test
[PATH_INFO] => /test
[REQUEST_URI] => /en/test?123
[QUERY_STRING] => 123
[REDIRECT_LANGUAGE] => en
回答by Beejor
PHP Paths
PHP 路径
????$_SERVER['REQUEST_URI'] ???=?Web path, requested URI
????$_SERVER['PHP_SELF'] ???=?Web path, requested file + path info
????$_SERVER['SCRIPT_NAME'] ???=?Web path, requested file
????$_SERVER['SCRIPT_FILENAME']???=?File path, requested file
????__FILE__ ???=?File path, current file
?
?? ??$_SERVER['REQUEST_URI'] ???=?Web 路径,请求的 URI
?? ??$_SERVER['PHP_SELF'] ???=?Web 路径,请求的文件 + 路径信息
?? ??$_SERVER['SCRIPT_NAME'] ???=?Web 路径,请求的文件
?? ??$_SERVER['SCRIPT_FILENAME']???=?文件路径,请求的文件
?? ??__FILE__ ???=?文件路径,当前文件
?
Where
在哪里
- File pathis a system file pathlike
/var/www/index.php, after alias resolution - Web pathis a server document pathlike
/index.phpfromhttp://foo.com/index.php, and may not even match any file - Current filemeans the included script file, not any script that includes it
- Requested filemeans the includer script file, not the included one
- URIis the HTTP requestlike
/index.php?foo=bar, before any URL rewriting - Path infois any extra Apache data located after the script name but before the query string
- 文件路径是系统文件路径,如
/var/www/index.php别名解析后 - Web 路径是一个类似于from
的服务器文档路径,甚至可能不匹配任何文件
/index.phphttp://foo.com/index.php - 当前文件是指包含的脚本文件,而不是包含它的任何脚本
- 请求的文件是指包含脚本文件,而不是包含的脚本文件
- URI是类似的HTTP 请求
/index.php?foo=bar,在任何 URL 重写之前 - 路径信息是位于脚本名称之后但在查询字符串之前的任何额外的 Apache 数据
Order of Operation
操作顺序
- Client sends server an HTTP request
REQUEST_URI - Server performs any URL rewritingfrom .htaccess files, etc. to get
PHP_SELF - Server separates
PHP_SELFintoSCRIPT_FILENAME+PATH_INFO - Server performs alias resolutionand converts the entire url pathto a system file pathto get
SCRIPT_FILENAME - Resulting script file may include others, where
__FILE__refers to the path to the current file
- 客户端向服务器发送HTTP 请求
REQUEST_URI - 服务器从 .htaccess 文件等执行任何URL 重写以获取
PHP_SELF - 服务器分离
PHP_SELF成SCRIPT_FILENAME+PATH_INFO - 服务器进行别名解析,将整个url路径转换为系统文件路径得到
SCRIPT_FILENAME - 生成的脚本文件可能包含其他脚本文件,其中
__FILE__指的是当前文件的路径
回答by Adam
You may want to look into the URI Classand make use of $this->uri->uri_string()
您可能需要查看URI 类并使用 $this->uri->uri_string()
Returns a string with the complete URI.
返回具有完整 URI 的字符串。
For example, if this is your full URL:
例如,如果这是您的完整网址:
http://example.com/index.php/news/local/345
The function would return this:
该函数将返回:
/news/local/345
Or you could make use of the segments to drill down specific areas without having to come up with parsing/regex values
或者您可以使用段来深入特定区域,而无需提出解析/正则表达式值
回答by Xenph Yan
Personally I use the $REQUEST_URIas it references the URI entered and not the location on the server's disc.
我个人使用 ,$REQUEST_URI因为它引用了输入的 URI,而不是服务器磁盘上的位置。
回答by Xenph Yan
There is very little to add to Odin's answer. I just felt to provide a complete example from the HTTP request to the actual file on the file system to illustrate the effects of URL rewriting and aliases. On the file system the script /var/www/test/php/script.phpis
奥丁的回答几乎没有什么可补充的。我只是觉得提供一个完整的例子,从HTTP请求到文件系统上的实际文件,来说明URL重写和别名的效果。在文件系统上,脚本/var/www/test/php/script.php是
<?php
include ("script_included.php")
?>
where /var/www/test/php/script_included.phpis
这里/var/www/test/php/script_included.php是
<?php
echo "REQUEST_URI: " . $_SERVER['REQUEST_URI'] . "<br>";
echo "PHP_SELF: " . $_SERVER['PHP_SELF'] . "<br>";
echo "QUERY_STRING: " . $_SERVER['QUERY_STRING'] . "<br>";
echo "SCRIPT_NAME: " . $_SERVER['SCRIPT_NAME'] . "<br>";
echo "PATH_INFO: " . $_SERVER['PATH_INFO'] . "<br>";
echo "SCRIPT_FILENAME: " . $_SERVER['SCRIPT_FILENAME'] . "<br>";
echo "__FILE__ : " . __FILE__ . "<br>";
?>
and /var/www/test/.htaccessis
并且 /var/www/test/.htaccess是
RewriteEngine On
RewriteRule before_rewrite/script.php/path/(.*) after_rewrite/script.php/path/
and the Apache configuration file includes the alias
并且 Apache 配置文件包含别名
Alias /test/after_rewrite/ /var/www/test/php/
and the http request is
而http请求是
www.example.com/test/before_rewrite/script.php/path/info?q=helloword
The output will be
输出将是
REQUEST_URI: /test/before_rewrite/script.php/path/info?q=helloword
PHP_SELF: /test/after_rewrite/script.php/path/info
QUERY_STRING: q=helloword
SCRIPT_NAME: /test/after_rewrite/script.php
PATH_INFO: /path/info
SCRIPT_FILENAME: /var/www/test/php/script.php
__FILE__ : /var/www/test/php/script_included.php
The following always holds
以下始终成立
PHP_SELF = SCRIPT_NAME + PATH_INFO = full url path between domain and query string.
If there is no mod_rewrite, mod_dir, ErrorDocument rewrite or any form of URL rewriting, we also have
如果没有 mod_rewrite、mod_dir、ErrorDocument 重写或任何形式的 URL 重写,我们也有
REQUEST_URI = PHP_SELF + ? + QUERY_STRING
The aliases affect the system file paths SCRIPT_FILENAMEand __FILE__, not the URL paths, which are defined before - see exceptions below. Aliases might use the entire URL path, including PATH_INFO. There could be no connection at all between SCRIPT_NAMEand SCRIPT_FILENAME.
别名影响系统的文件路径SCRIPT_FILENAME和__FILE__,而不是URL路径,这是以前定义-见下文例外。别名可能会使用整个 URL 路径,包括PATH_INFO. SCRIPT_NAME和之间根本没有联系SCRIPT_FILENAME。
It is not totally exact that aliases are not resolved at the time the URL path [PHP_SELF] = [SCRIPT_NAME] + [PATH_INFO]is defined, because aliases are considered to search the file system and we know from example 4 in Odin's answer that the file system is searched to determine if the file exists, but this is only relevant when the file is not found. Similarly, mod_dir calls mod_alias to search the file system, but this is only relevant if you have an alias such as Alias \index.php \var\www\index.phpand the request uri is a directory.
在[PHP_SELF] = [SCRIPT_NAME] + [PATH_INFO]定义URL 路径时不解析别名并不完全准确,因为别名被认为是搜索文件系统,我们从 Odin 回答中的示例 4 中知道搜索文件系统以确定文件是否存在,但这仅在找不到文件时才相关。类似地,mod_dir 调用 mod_alias 来搜索文件系统,但这仅在您有一个别名Alias \index.php \var\www\index.php并且请求 uri 是一个目录时才相关。
回答by Absolute?ER?
If you ever forget which variables do what, you can write a little script that uses phpinfo()and call it from a URL with a query string. Since server software installations present the variables that PHP returns it's always a good idea to check the machine's output in case rewrites at the server config file are causing different results than expected. Save it as something like _inf0.php:
如果您忘记了哪些变量做什么,您可以编写一个使用phpinfo()的小脚本,并从带有查询字符串的 URL 中调用它。由于服务器软件安装会显示 PHP 返回的变量,因此检查机器的输出总是一个好主意,以防服务器配置文件中的重写导致与预期不同的结果。将其另存为_inf0.php:
<?php
$my_ip = '0.0.0.0';
if($_SERVER['REMOTE_ADDR']==$my_ip){
phpinfo();
} else {
//something
}
Then you would call /_inf0.php?q=500
然后你会打电话 /_inf0.php?q=500
回答by Absolute?ER?
Backup a second, you've taken the wrong approach to begin with. Why not just do this
备份一秒钟,您一开始就采取了错误的方法。为什么不这样做
RewriteEngine on
RewriteCond !^(images|inc|favicon\.ico|index\.php|robots\.txt)
RewriteRule ^(.*)$ /index.php?url= [L]
instead? Then grab it with $_GET['url'];
反而?然后用它抓住它$_GET['url'];

