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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 22:13:23  来源:igfitidea点击:

PHP_SELF vs PATH_INFO vs SCRIPT_NAME vs REQUEST_URI

httpphpcodeigniter

提问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_URIPATH_INFO等获取它,但我正在尝试确定哪个最可靠。没有人知道(或不知道在哪里可以找到)之间的真正区别PHP_SELFPATH_INFOSCRIPT_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):

http://example.com/test.php

http://example.com/test.php

[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

http://domain.com/

http://domain.com/

[PHP_SELF]     => /index.php
[PATH_INFO] IS NOT AVAILABLE (fallback to REQUEST_URI in your script)
[REQUEST_URI]  => /
[QUERY_STRING] => 

Path

小路

http://domain.com/test

http://domain.com/test

[PHP_SELF]     => /index.php/test
[PATH_INFO]    => /test
[REQUEST_URI]  => /test
[QUERY_STRING] => 

Query String

请求参数

http://domain.com/test?123

http://domain.com/test?123

[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

http://domain.com/

http://domain.com/

[REQUEST_URI]  => /
[QUERY_STRING] => 

Path

小路

http://domain.com/test

http://domain.com/test

[REQUEST_URI]  => /test
[QUERY_STRING] => url=test

Query String

请求参数

http://domain.com/test?123

http://domain.com/test?123

[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

http://domain.com/

http://domain.com/

[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

小路

http://domain.com/test

http://domain.com/test

[PHP_SELF]          => /index.php/test
[PATH_INFO]         => /test
[REQUEST_URI]       => /test
[QUERY_STRING]      => 
[REDIRECT_LANGUAGE] => 

Language

http://domain.com/en

http://domain.com/en

[PHP_SELF]          => /index.php/
[PATH_INFO]         => /
[REQUEST_URI]       => /en
[QUERY_STRING]      => 
[REDIRECT_LANGUAGE] => en

Language path

语言路径

http://domain.com/en/test

http://domain.com/en/test

[PHP_SELF]          => /index.php/test
[PATH_INFO]         => /test
[REQUEST_URI]       => /en/test
[REDIRECT_LANGUAGE] => en

Language Query string

语言查询字符串

http://domain.com/en/test?123

http://domain.com/en/test?123

[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.phpfrom http://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

操作顺序

  1. Client sends server an HTTP requestREQUEST_URI
  2. Server performs any URL rewritingfrom .htaccess files, etc. to get PHP_SELF
  3. Server separates PHP_SELFinto SCRIPT_FILENAME+ PATH_INFO
  4. Server performs alias resolutionand converts the entire url pathto a system file pathto get SCRIPT_FILENAME
  5. Resulting script file may include others, where __FILE__refers to the path to the current file
  1. 客户端向服务器发送HTTP 请求REQUEST_URI
  2. 服务器从 .htaccess 文件等执行任何URL 重写以获取PHP_SELF
  3. 服务器分离PHP_SELFSCRIPT_FILENAME+PATH_INFO
  4. 服务器进行别名解析,将整个url路径转换为系统文件路径得到SCRIPT_FILENAME
  5. 生成的脚本文件可能包含其他脚本文件,其中__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'];