[英]PHP_SELF vs PATH_INFO vs SCRIPT_NAME vs REQUEST_URI
我正在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看到了下划線,並且由於某種原因使其變為斜體。
更新 :修復了空格。
這些變量之間差異的一些實際例子:
示例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
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
$_SERVER['REQUEST_URI']
= Web路徑,請求的URI
$_SERVER['PHP_SELF']
= Web路徑,請求的文件+路徑信息
$_SERVER['SCRIPT_NAME']
=網絡路徑,請求的文件
$_SERVER['SCRIPT_FILENAME']
=文件路徑,請求的文件
__FILE__
=文件路徑,當前文件
/var/www/index.php
,別名解析后 http://foo.com/index.php
/index.php
,甚至可能不匹配任何文件 /index.php?foo=bar
這樣的HTTP請求 REQUEST_URI
PHP_SELF
PHP_SELF
分隔為SCRIPT_FILENAME
+ PATH_INFO
SCRIPT_FILENAME
__FILE__
指的是當前文件的路徑 您可能希望查看URI類並使用$ this-> uri-> uri_string()
返回包含完整URI的字符串。
例如,如果這是您的完整網址:
http://example.com/index.php/news/local/345
該函數將返回此:
/news/local/345
或者您可以利用這些段來深入挖掘特定區域,而無需提供解析/正則表達式值
我個人使用$REQUEST_URI
因為它引用了輸入的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
並且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是目錄時才有意義。
如果您忘記了哪些變量做了什么,您可以編寫一個使用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
備份一秒,你采取了錯誤的方法開始。 為什么不這樣做呢
RewriteEngine on
RewriteCond $1 !^(images|inc|favicon\.ico|index\.php|robots\.txt)
RewriteRule ^(.*)$ /index.php?url=$1 [L]
代替? 然后用$_GET['url'];
抓住它$_GET['url'];
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.