簡體   English   中英

PHP_SELF vs PATH_INFO vs SCRIPT_NAME vs REQUEST_URI

[英]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_URIPATH_INFO等獲得它,但我想確定哪個最可靠。 有誰知道(或知道在哪里找到) PHP_SELFPATH_INFOSCRIPT_NAMEREQUEST_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):

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

PHP文檔可以告訴您區別:

當前正在執行的腳本的文件名,相對於文檔根目錄。 in a script at the address would be . 例如,地址為的腳本中的將為 __FILE__常量包含當前(即包含)文件的完整路徑和文件名。 如果PHP作為命令行處理器運行,則此變量包含自PHP 4.3.0以來的腳本名稱。 以前它不可用。

包含當前腳本的路徑。 這對需要指向自己的頁面很有用。 __FILE__常量包含當前(即包含)文件的完整路徑和文件名。

為訪問此頁面而給出的URI; . 例如,

PATH_INFO似乎沒有記錄......

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

PHP路徑

$_SERVER['REQUEST_URI'] = Web路徑,請求的URI
$_SERVER['PHP_SELF'] = Web路徑,請求的文件+路徑信息
$_SERVER['SCRIPT_NAME'] =網絡路徑,請求的文件
$_SERVER['SCRIPT_FILENAME'] =文件路徑,請求的文件
__FILE__ =文件路徑,當前文件

哪里

  • 文件路徑就像是一個系統文件路徑 /var/www/index.php ,別名解析后
  • Web路徑是一個服務器文檔路徑,http://foo.com/index.php /index.php ,甚至可能不匹配任何文件
  • 當前文件表示包含的腳本文件 ,而不是包含它的任何腳本
  • 請求的文件表示包含者腳本文件 ,而不是包含的文件
  • 在重寫任何URL之前, URI是像/index.php?foo=bar這樣的HTTP請求
  • 路徑信息是位於腳本名稱之后但位於查詢字符串之前的任何額外Apache數據

運作順序

  1. 客戶端向服務器發送HTTP請求 REQUEST_URI
  2. 服務器從.htaccess文件等執行任何URL重寫以獲取PHP_SELF
  3. 服務器將PHP_SELF分隔為SCRIPT_FILENAME + PATH_INFO
  4. 服務器執行別名解析並將整個URL路徑轉換為系統文件路徑以獲取SCRIPT_FILENAME
  5. 生成的腳本文件可能包含其他文件,其中__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_NAMESCRIPT_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM