我正在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_URI
,PATH_INFO
等处获得它,但我正在尝试确定哪个最可靠。有谁知道(或知道在哪里找到)PHP_SELF
,PATH_INFO
,SCRIPT_NAME
和REQUEST_URI
之间的真正区别?谢谢你的帮助!
注意:我必须添加空格,因为SO看到了下划线,并且由于某种原因使其变为斜体。
已更新:修正了空格。
答案 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):
[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时才可用:
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] =>
[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
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] =>
[REQUEST_URI] => /test
[QUERY_STRING] => url=test
[REQUEST_URI] => /test?123
[QUERY_STRING] => url=test&123
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
[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
[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
[PHP_SELF] => /index.php/test
[PATH_INFO] => /test
[REQUEST_URI] => /en/test
[REDIRECT_LANGUAGE] => en
[PHP_SELF] => /index.php/test
[PATH_INFO] => /test
[REQUEST_URI] => /en/test?123
[QUERY_STRING] => 123
[REDIRECT_LANGUAGE] => en
答案 3 :(得分:8)
$_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
,甚至可能无法匹配任何文件/index.php?foo=bar
REQUEST_URI
PHP_SELF
PHP_SELF
分隔为SCRIPT_FILENAME
+ PATH_INFO
SCRIPT_FILENAME
__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_INFO
。 SCRIPT_NAME
和SCRIPT_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'];