PHP_SELF vs PATH_INFO vs SCRIPT_NAME vs REQUEST_URI

时间:2008-11-11 04:00:17

标签: http php codeigniter

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

规则如下:

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

通常,我只会检查php_self,但在这种情况下,它始终是index.php。我可以从REQUEST_URIPATH_INFO等处获得它,但我正在尝试确定哪个最可靠。有谁知道(或知道在哪里找到)PHP_SELFPATH_INFOSCRIPT_NAMEREQUEST_URI之间的真正区别?谢谢你的帮助!

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

已更新:修正了空格。

9 个答案:

答案 0 :(得分:215)

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

[PHP_SELF] => /test.php/foo/bar
[SCRIPT_NAME] => /test.php

(这似乎是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

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

http://example.com/test.php

[REQUEST_URI] => /test.php
[SCRIPT_NAME] => /test2.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

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

[SCRIPT_NAME] => /404error.php
[REQUEST_URI] => /404error.php?404;http://example.com/test.php

答案 1 :(得分:49)

PHP documentation可以告诉您不同之处:

  

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

答案 2 :(得分:20)

PATH_INFO仅在使用htaccess时才可用:

示例1

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

保持不变

[SCRIPT_NAME] => /index.php

http://domain.com/

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

路径

http://domain.com/test

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

查询字符串

http://domain.com/test?123

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

示例2

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

保持不变

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

http://domain.com/

[REQUEST_URI]  => /
[QUERY_STRING] => 

路径

http://domain.com/test

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

查询字符串

http://domain.com/test?123

[REQUEST_URI]  => /test?123
[QUERY_STRING] => url=test&123

示例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]

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]

保持不变

[SCRIPT_NAME] => /index.php

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

路径

http://domain.com/test

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

语言

http://domain.com/en

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

语言路径

http://domain.com/en/test

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

语言查询字符串

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

答案 3 :(得分:8)

PHP路径

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

其中

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

运作顺序

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

答案 4 :(得分:4)

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

返回包含完整URI的字符串。

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

http://example.com/index.php/news/local/345

该函数将返回:

/news/local/345

或者您可以利用这些段来深入挖掘特定区域,而无需提供解析/正则表达式值

答案 5 :(得分:3)

我个人使用$REQUEST_URI,因为它引用了输入的URI,而不是服务器光盘上的位置。

答案 6 :(得分:3)

奥丁的答案几乎没有什么可补充的。我只想提供从HTTP请求到文件系统上的实际文件的完整示例,以说明URL重写和别名的影响。在文件系统上,脚本/var/www/test/php/script.php

<?php
include ("script_included.php")
?>

其中/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>";  
?>

/var/www/test/.htaccess

RewriteEngine On
RewriteRule before_rewrite/script.php/path/(.*) after_rewrite/script.php/path/$1 

,Apache配置文件包含别名

Alias /test/after_rewrite/ /var/www/test/php/

,http请求

www.example.com/test/before_rewrite/script.php/path/info?q=helloword

输出

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

以下内容始终存在

PHP_SELF = SCRIPT_NAME + PATH_INFO = full url path between domain and query string. 

如果没有mod_rewrite,mod_dir,ErrorDocument重写或任何形式的URL重写,我们也有

REQUEST_URI = PHP_SELF + ? + QUERY_STRING 

别名会影响系统文件路径SCRIPT_FILENAME__FILE__,而不会影响之前定义的URL路径 - 请参阅下面的例外情况。别名可能使用整个URL路径,包括PATH_INFOSCRIPT_NAMESCRIPT_FILENAME之间可能没有任何关联。

在定义URL路径[PHP_SELF] = [SCRIPT_NAME] + [PATH_INFO]时,别名未解析并不完全准确,因为别名被认为是搜索文件系统,我们从Odin的答案中的示例4中知道搜索文件系统以确定文件是否存在,但这仅在找不到文件时才相关。类似地,mod_dir调用mod_alias来搜索文件系统,但只有当您拥有Alias \index.php \var\www\index.php等别名并且请求uri是目录时,这才有意义。

答案 7 :(得分:0)

如果您忘记了哪个变量在做什么,则可以编写一个使用phpinfo()的小脚本,然后从带有查询字符串的URL中调用它。由于服务器软件安装提供了PHP返回的变量,因此最好检查计算机的输出,以防在服务器配置文件上进行重写导致结果与预期不同。将其另存为_inf0.php

<?php
    $my_ip = '0.0.0.0';

   if($_SERVER['REMOTE_ADDR']==$my_ip){
     phpinfo();
   } else {
     //something
   }

然后您将呼叫/_inf0.php?q=500

答案 8 :(得分:-2)

备份一秒,你采取了错误的方法开始。为什么不这样做呢

RewriteEngine on
RewriteCond $1 !^(images|inc|favicon\.ico|index\.php|robots\.txt)
RewriteRule ^(.*)$ /index.php?url=$1 [L]

代替?然后使用$_GET['url'];

抓住它