PHP_SELF vs PATH_INFO vs SCRIPT_NAME vs REQUEST_URI

Eli*_*Eli 101 php codeigniter http

我正在CodeIgniter中构建一个PHP应用程序.CodeIgniter将所有请求发送到主控制器:index.php.但是,我不喜欢index.php在URI中看到.例如,http://www.example.com/faq/whatever将路由到http://www.example.com/index.php/faq/whatever.我需要一种可靠的方法让脚本知道它的地址是什么,因此它将知道如何处理导航.我mod_rewrite按照CodeIgniter文档使用过.

规则如下:

RewriteEngine on
RewriteCond $1 !^(images|inc|favicon\.ico|index\.php|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L] 
Run Code Online (Sandbox Code Playgroud)

通常,我会检查php_self,但在这种情况下,它总是index.php.我可以得到它REQUEST_URI,PATH_INFO等等,但我想,以决定这将是最可靠的.有谁知道(或不知道在哪里可以找到)之间的真正区别PHP_SELF,PATH_INFO,SCRIPT_NAME,和REQUEST_URI?谢谢你的帮助!

注意:我必须添加空格,因为SO看到了下划线,并且由于某种原因使其变为斜体.

更新:修复了空格.

Odi*_*din 222

这些变量之间差异的一些实际示例:
示例1. 当请求的url处于以下形式时,PHP_SELF与SCRIPT_NAME不同:http:
//example.com/test.php/foo/bar

[PHP_SELF] => /test.php/foo/bar
[SCRIPT_NAME] => /test.php
Run Code Online (Sandbox Code Playgroud)

(这似乎是PATH_INFO包含敏感信息的唯一情况[PATH_INFO] =>/foo/bar)注意:这在一些较旧的PHP版本(<= 5.0?)中曾经有所不同.

示例2.当输入非空查询字符串时,REQUEST_URI与SCRIPT_NAME不同:http:
//example.com/test.php?foo = bar

[SCRIPT_NAME] => /test.php
[REQUEST_URI] => /test.php?foo=bar
Run Code Online (Sandbox Code Playgroud)

示例3.当服务器端重定向生效时,REQUEST_URI与SCRIPT_NAME不同(例如,apache上的mod_rewrite):

http://example.com/test.php

[REQUEST_URI] => /test.php
[SCRIPT_NAME] => /test2.php
Run Code Online (Sandbox Code Playgroud)

示例4.使用脚本处理HTTP错误时,REQUEST_URI与SCRIPT_NAME不同.
使用apache指令ErrorDocument 404 /404roro.php
http://example.com/test.php

[REQUEST_URI] => /test.php
[SCRIPT_NAME] => /404error.php
Run Code Online (Sandbox Code Playgroud)

在IIS服务器上使用自定义错误页面
http://example.com/test.php

[SCRIPT_NAME] => /404error.php
[REQUEST_URI] => /404error.php?404;http://example.com/test.php
Run Code Online (Sandbox Code Playgroud)

  • +1,"一个例子不是学习的方式,这是学习的唯一方法." - 我总是要重新检查这些东西,对404错误进行非常好的研究.=) (21认同)
  • +1:我生命中第一次理解差异.他们应该用您的答案更新PHP文档 (16认同)

Jer*_*ten 50

PHP文件可以告诉你的区别:

'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似乎没有记录......

  • 这很可能不是关于PHP文档而是关于CGI :)并且有PATH_INFO记录:http://tools.ietf.org/html/rfc3875#section-4但是有一些已知的问题,Apache和nginx并不总是给出这个变量. (3认同)
  • -1就像对我为什么投票的解释:我来这篇文章的全部原因是因为文档不清晰。奥丁(Odin)在下面的回答清楚地解释了这些变量之间的区别。我觉得仅复制和粘贴容易找到的文档还是不够的答案是不够的。我相信大多数人都必须已经访问过该文档才能了解上述$ _SERVER变量中的元素列表。 (2认同)

Mik*_*ike 23

PATH_INFO 只有在使用像这样的htaccess时才可用:

例1

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^(favicon\.ico|robots\.txt)
RewriteRule ^(.*)$ index.php/$1 [L]
Run Code Online (Sandbox Code Playgroud)

保持原样

[SCRIPT_NAME] => /index.php
Run Code Online (Sandbox Code Playgroud)

http://domain.com/

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

路径

http://domain.com/test

[PHP_SELF]     => /index.php/test
[PATH_INFO]    => /test
[REQUEST_URI]  => /test
[QUERY_STRING] => 
Run Code Online (Sandbox Code Playgroud)

请求参数

http://domain.com/test?123

[PHP_SELF]     => /index.php/test
[PATH_INFO]    => /test
[REQUEST_URI]  => /test?123
[QUERY_STRING] => 123
Run Code Online (Sandbox Code Playgroud)

例2

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^(favicon\.ico|robots\.txt)
RewriteRule ^(.*)$ index.php?url=$1 [L,QSA]
Run Code Online (Sandbox Code Playgroud)

保持原样

[SCRIPT_NAME]  => /index.php
[PHP_SELF]     => /index.php
[PATH_INFO] IS NOT AVAILABLE (fallback to REQUEST_URI in your script)
Run Code Online (Sandbox Code Playgroud)

http://domain.com/

[REQUEST_URI]  => /
[QUERY_STRING] => 
Run Code Online (Sandbox Code Playgroud)

路径

http://domain.com/test

[REQUEST_URI]  => /test
[QUERY_STRING] => url=test
Run Code Online (Sandbox Code Playgroud)

请求参数

http://domain.com/test?123

[REQUEST_URI]  => /test?123
[QUERY_STRING] => url=test&123
Run Code Online (Sandbox Code Playgroud)

例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/$5 [NC,L,E=LANGUAGE:$2$4]
Run Code Online (Sandbox Code Playgroud)

要么

RewriteRule ^([a-z]{2})(/(.*))?$ $3 [NC,L,E=LANGUAGE:$1]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^(favicon\.ico|robots\.txt)
RewriteRule ^(.*)$ index.php/$1 [L]
Run Code Online (Sandbox Code Playgroud)

保持原样

[SCRIPT_NAME] => /index.php
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

路径

http://domain.com/test

[PHP_SELF]          => /index.php/test
[PATH_INFO]         => /test
[REQUEST_URI]       => /test
[QUERY_STRING]      => 
[REDIRECT_LANGUAGE] => 
Run Code Online (Sandbox Code Playgroud)

语言

http://domain.com/en

[PHP_SELF]          => /index.php/
[PATH_INFO]         => /
[REQUEST_URI]       => /en
[QUERY_STRING]      => 
[REDIRECT_LANGUAGE] => en
Run Code Online (Sandbox Code Playgroud)

语言路径

http://domain.com/en/test

[PHP_SELF]          => /index.php/test
[PATH_INFO]         => /test
[REQUEST_URI]       => /en/test
[REDIRECT_LANGUAGE] => en
Run Code Online (Sandbox Code Playgroud)

语言查询字符串

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
Run Code Online (Sandbox Code Playgroud)


Bee*_*jor 10

PHP路径

  ??$_SERVER['REQUEST_URI'] ?? = Web路径,请求的URI
  ??$_SERVER['PHP_SELF'] ?? = Web路径,请求的文件+路径信息
  ??$_SERVER['SCRIPT_NAME'] ?? = Web路径,请求的文件
  ??$_SERVER['SCRIPT_FILENAME']?? =文件路径,请求的文件
  ??__FILE__ ?? =文件路径,当前文件

哪里

  • 文件路径系统文件路径一样/var/www/index.php,别名解析后
  • 网络路径服务器文件的路径一样/index.phphttp://foo.com/index.php,并且甚至可能不匹配任何文件
  • 当前文件表示包含的脚本文件,而不是包含它的任何脚本
  • 请求的文件表示包含者脚本文件,而不是包含的文件
  • URIHTTP请求/index.php?foo=bar,任何URL重写之前
  • 路径信息是位于脚本名称之后但位于查询字符串之前的任何额外Apache数据

运作顺序

  1. 客户端向服务器发送HTTP请求 REQUEST_URI
  2. 服务器从.htaccess文件等执行任何URL重写PHP_SELF
  3. 服务器PHP_SELF分为SCRIPT_FILENAME+PATH_INFO
  4. 服务器执行别名解析并将整个URL路径转换为要获取的系统文件路径SCRIPT_FILENAME
  5. 生成的脚本文件可能包含其他文件,其中__FILE__指的是当前文件的路径


Ada*_*dam 5

您可能需要查看URI 类并使用 $this->uri->uri_string()

返回具有完整 URI 的字符串。

例如,如果这是您的完整网址:

http://example.com/index.php/news/local/345
Run Code Online (Sandbox Code Playgroud)

该函数将返回:

/news/local/345
Run Code Online (Sandbox Code Playgroud)

或者您可以使用段来深入特定区域,而无需提出解析/正则表达式值