PHP_SELF与PATH_INFO对比SCRIPT_NAME与REQUEST_URI
我正在CodeIgniter中构build一个PHP应用程序。 CodeIgniter发送所有请求到主控制器: index.php
。 但是,我不喜欢在URI中看到index.php
。 例如, 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]
通常情况下,我只是检查php_self
,但在这种情况下,它总是index.php
。 我可以从REQUEST_URI
, PATH_INFO
等得到它,但我正在试图决定哪一个最可靠。 有谁知道(或知道在哪里可以find) PHP_SELF
, PATH_INFO
, SCRIPT_NAME
和REQUEST_URI
之间的真正区别吗? 谢谢你的帮助!
注意 :我不得不添加空格,因为我们看到了下划线,并且由于某种原因使它变为斜体。
更新 :修复了空格。
PHP文档可以告诉你不同之处:
'PHP_SELF'
当前正在执行的脚本相对于文档根目录的文件名。 例如,位于http://example.com/test.php/foo.bar的脚本中的$ _SERVER ['PHP_SELF']将是/test.php/foo.bar 。 __FILE__常量包含当前(即包含)文件的完整path和文件名。 如果PHP作为命令行处理器运行,则此variables包含自PHP 4.3.0起的脚本名称。 以前它不可用。
'SCRIPT_NAME'
包含当前脚本的path。 这对于需要指向自己的页面非常有用。 __FILE__常量包含当前(即包含)文件的完整path和文件名。
'REQUEST_URI'
为了访问此页面而提供的URI; 比如“/index.html” 。
PATH_INFO似乎没有logging…
这些variables之间差异的一些实际例子:
示例1. PHP_SELF 仅在请求的URL在表单中时与SCRIPT_NAME不同:
http://example.com/test.php/foo/bar
[PHP_SELF] => /test.php/foo/bar [SCRIPT_NAME] => /test.php
(这似乎是唯一的情况下,当PATH_INFO包含明智的信息[PATH_INFO] => /富/酒吧)注意:这在一些旧的PHP版本(<= 5.0?)是不同的。
示例2.input非空查询string时,REQUEST_URI与SCRIPT_NAME不同:
http://example.com/test.php?foo=bar
[SCRIPT_NAME] => /test.php [REQUEST_URI] => /test.php?foo=bar
例3.当服务器端的redirecton生效时,REQUEST_URI和SCRIPT_NAME是不同的(例如apache上的mod_rewrite):
[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
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
根
[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] =>
请求参数
[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)
根
[REQUEST_URI] => / [QUERY_STRING] =>
path
[REQUEST_URI] => /test [QUERY_STRING] => url=test
请求参数
[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 ^(([az]{2})|(([az]{2})/)?(.*))$ index.php/$5 [NC,L,E=LANGUAGE:$2$4]
要么
RewriteRule ^([az]{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
根
[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] =>
语言
[PHP_SELF] => /index.php/ [PATH_INFO] => / [REQUEST_URI] => /en [QUERY_STRING] => [REDIRECT_LANGUAGE] => en
语言path
[PHP_SELF] => /index.php/test [PATH_INFO] => /test [REQUEST_URI] => /en/test [REDIRECT_LANGUAGE] => en
语言查询string
[PHP_SELF] => /index.php/test [PATH_INFO] => /test [REQUEST_URI] => /en/test?123 [QUERY_STRING] => 123 [REDIRECT_LANGUAGE] => en
PHPpath
$_SERVER['REQUEST_URI']
= Webpath,请求的URI
$_SERVER['PHP_SELF']
= Webpath,请求的文件+path信息
$_SERVER['SCRIPT_NAME']
= Webpath,请求的文件
$_SERVER['SCRIPT_FILENAME']
=文件path,请求的文件
__FILE__
=文件path,当前文件
哪里
- 文件path是一个系统文件path,如
/var/www/index.php
,别名parsing后 - Webpath是一个服务器文档path,如
http://foo.com/index.php
/index.php
,甚至可能不匹配任何文件 - 当前文件意味着包含的脚本文件 ,而不是包含它的任何脚本
- 请求的文件意味着includer脚本文件 ,而不是包含的文件
- 在任何URL重写之前, URI都是
/index.php?foo=bar
这样的HTTP请求 - path信息是位于脚本名称之后但位于查询string之前的任何额外的Apache数据
操作顺序
- 客户端向服务器发送一个HTTP请求
REQUEST_URI
- 服务器执行从.htaccess文件等任何URL重写获取
PHP_SELF
- 服务器将
PHP_SELF
分隔为SCRIPT_FILENAME
+PATH_INFO
- 服务器执行别名parsing并将整个urlpath转换为系统文件path以获取
SCRIPT_FILENAME
- 生成的脚本文件可能包含其他文件,其中
__FILE__
引用当前文件的path
您可能希望查看URI类并使用$ this-> uri-> uri_string()
返回一个完整URI的string。
例如,如果这是您的完整url:
http://example.com/index.php/news/local/345
该函数将返回这个:
/news/local/345
或者,您可以利用这些细分来深入了解特定区域,而不必提出parsing/正则expression式值
我个人使用$REQUEST_URI
因为它引用input的URI,而不是服务器光盘上的位置。
奥丁的答案几乎没有增加。 我只是想从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
Apacheconfiguration文件包含别名
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重写或任何forms的URL重写,我们也有
REQUEST_URI = PHP_SELF + ? + QUERY_STRING
别名影响系统文件pathSCRIPT_FILENAME
和__FILE__
,而不是之前定义的URLpath – 请参阅下面的例外。 别名可能会使用整个URLpath,包括PATH_INFO
。 SCRIPT_NAME
和SCRIPT_FILENAME
之间根本没有连接。
在定义URLpath[PHP_SELF] = [SCRIPT_NAME] + [PATH_INFO]
,别名不能被parsing,因为别名被认为是search文件系统,我们从Odin的答案的例子4中知道文件系统被search以确定文件是否存在,但是这只在找不到该文件时才有意义。 类似地,mod_dir调用mod_alias来search文件系统,但是这只有在别名(如Alias \index.php \var\www\index.php
和请求URI是一个目录时才有意义。
备份第二个,你已经采取了错误的做法开始。 为什么不这样做呢
RewriteEngine on RewriteCond $1 !^(images|inc|favicon\.ico|index\.php|robots\.txt) RewriteRule ^(.*)$ /index.php?url=$1 [L]
代替? 然后用$_GET['url'];
抓住它$_GET['url'];