国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

PHP_SELF變量解析和重復(fù)路徑解決

zebrayoung / 1970人閱讀

摘要:是通用網(wǎng)管協(xié)議,用于讓交互程序和服務(wù)器通信的協(xié)議。的超全局變量是一個(gè)包含了諸如頭信息路徑以及腳本位置等等信息的數(shù)組。常量包含當(dāng)前例如包含文件的完整路徑和文件名。包含當(dāng)前腳本的路徑。這就是整個(gè)關(guān)于解析請(qǐng)求信息的流程。

最近升級(jí)PHPPHP7版本,并重新部署了新的Nginx,啟動(dòng)的時(shí)候發(fā)現(xiàn)了一個(gè)問(wèn)題,全局變量$_SERVER["PHP_SELF"]的值發(fā)生了改變,從而影響到代碼的功能。因此我們來(lái)了解下$_SERVER全局變量中的PHP_SELF/PATH_INFO/SCRIPT_NAME等參數(shù)以及其關(guān)系。

CGI 1.1規(guī)范

之前的文章 [ php-fpm進(jìn)程數(shù)管理 ] 已經(jīng)簡(jiǎn)單說(shuō)過(guò)CGI的內(nèi)容,這里我們?cè)僭敿?xì)講一下。

CGICommon Gateway Interface(通用網(wǎng)管協(xié)議),用于讓交互程序和Web服務(wù)器通信的協(xié)議。它負(fù)責(zé)處理URL的請(qǐng)求,啟動(dòng)一個(gè)進(jìn)程,將客戶端發(fā)送的數(shù)據(jù)作為輸入,由Web服務(wù)器收集程序的輸出并加上合適的頭部,再發(fā)送回客戶端。

FastCGI是基于CGI的增強(qiáng)版本的協(xié)議,不同于創(chuàng)建新的進(jìn)程來(lái)服務(wù)請(qǐng)求,使用持續(xù)的進(jìn)程和創(chuàng)建的子進(jìn)程來(lái)處理一連串的進(jìn)程,這些進(jìn)程由FastCGI服務(wù)器管理,開銷更小,效率更高。

CGI誕生于1993年美國(guó)國(guó)家計(jì)算機(jī)中心,目的是為不同的動(dòng)態(tài)頁(yè)面處理語(yǔ)言(php/python/java)在不同的服務(wù)器下(apache/nginx)提供一致的接口規(guī)范,提供會(huì)話環(huán)境變量、會(huì)話客戶端等信息。

在RFC-CGI1.1文檔中包含了協(xié)議的全部?jī)?nèi)容,我們現(xiàn)在只關(guān)注它的 4.1節(jié):Request Meta-Variables 。

標(biāo)準(zhǔn)中定義了處理請(qǐng)求應(yīng)該實(shí)現(xiàn)的17個(gè)屬性和如何自定義新屬性,比如:

SERVER_PROTOCOL :信息協(xié)議的名字和修訂版。格式為protocol/reVision 。

SERVER_PORT :發(fā)送請(qǐng)求的端口號(hào)。

REQUEST_METHOD :請(qǐng)求的方法。對(duì)于HTTP,有"GET"、 "HEAD"、 "POST"等等。

PATH_INFO :額外的路徑信息,由客戶端給出的。換句話說(shuō),腳本可以由他們的虛擬路徑名來(lái)訪問(wèn),在這個(gè)路徑的末尾附帶額外的信息。這個(gè)額外信息被作為PATH_INFO發(fā)送。這個(gè)信息如果在傳遞給CGI腳本之前來(lái)自URL就可以由服務(wù)器來(lái)解碼。

PATH_TRANSLATED :服務(wù)器提供了一個(gè)PATH_INFO的轉(zhuǎn)換版本,它需要路徑并且為它做虛擬到物理的映射。

SCRIPT_NAME :將要執(zhí)行的腳本的一個(gè)虛擬路徑。

QUERY_STRING :在引用腳本的URL中緊跟在?之后的信息。這是一個(gè)查詢信息。它不能以任何方式來(lái)解碼。這個(gè)變量總是可以在有查詢信息的時(shí)候被設(shè)置,而不管命令行解碼。

REMOTE_HOST :產(chǎn)生請(qǐng)求的主機(jī)名。如果服務(wù)器沒有這個(gè)信息,它應(yīng)該設(shè)置REMOTE_ADDR 并且讓這個(gè)為未設(shè)置狀態(tài)。

REMOTE_ADDR :產(chǎn)生請(qǐng)求的遠(yuǎn)程主機(jī)的IP地址。

AUTH_TYPE :如果服務(wù)器支持用戶驗(yàn)證,腳本就受保護(hù)。這是一個(gè)協(xié)議規(guī)范授權(quán)方法,用于驗(yàn)證用戶。

REMOTE_USER :如果服務(wù)器支持用戶驗(yàn)證,腳本就受保護(hù)。這是他們授權(quán)的用戶名。

REMOTE_IDENT :如果HTTP服務(wù)器支持RFC931認(rèn)證,這個(gè)變量將被設(shè)置為從服務(wù)器取出的遠(yuǎn)程用戶名。這個(gè)變量的用法應(yīng)該只限制在登陸的時(shí)候。

CONTENT_TYPE :對(duì)于哪些已經(jīng)附上信息的請(qǐng)求,比如 HTTP POSTPUT,這是數(shù)據(jù)的內(nèi)容類型。

CONTENT_LENGTH :客戶端給的數(shù)據(jù)內(nèi)容的長(zhǎng)度。

這些變量需要各個(gè)語(yǔ)言和服務(wù)器進(jìn)行自己的實(shí)現(xiàn),同時(shí)他們也會(huì)有自己定義的一些變量。如我們今天要說(shuō)的PHP語(yǔ)言中的$_SERVER["PHP_SELF"]變量。

PHP的超全局變量$_SERVER
$_SERVER 是一個(gè)包含了諸如頭信息(header)、路徑(path)、以及腳本位置(script locations)等等信息的數(shù)組。這個(gè)數(shù)組中的項(xiàng)目由 Web 服務(wù)器創(chuàng)建。不能保證每個(gè)服務(wù)器都提供全部項(xiàng)目;服務(wù)器可能會(huì)忽略一些,或者提供一些沒有在這里列舉出來(lái)的項(xiàng)目。這也就意味著大量的此類變量都會(huì)在? CGI 1.1 規(guī)范中說(shuō)明,所以應(yīng)該仔細(xì)研究一下。

__FILE__ 常量包含當(dāng)前(例如包含)文件的完整路徑和文件名。

與此相關(guān)的,我們這里主要關(guān)注的幾個(gè)變量是:

PHP_SELF: 當(dāng)前執(zhí)行腳本的文件名,與 document root 有關(guān)。例如,在地址為 http://example.com/foo/bar.php 的腳本中值為 /foo/bar.php。

SCRIPT_NAME: 包含當(dāng)前腳本的路徑。這在頁(yè)面需要指向自己時(shí)非常有用。

PATH_INFO: 包含由客戶端提供的、跟在真實(shí)腳本名稱之后并且在查詢語(yǔ)句(query string)之前的路徑信息,如果存在的話。例如,如果當(dāng)前腳本是通過(guò) URL http://www.example.com/php/path_info.php/some/stuff?foo=bar 被訪問(wèn),那么值為 /some/stuff

文檔里表述的Web服務(wù)器,在我的環(huán)境里指代的是Nginx。在Apache中,當(dāng)不加配置的時(shí)候?qū)τ?b>PHP腳本, AcceptPathInfo是默認(rèn)接受的。而對(duì)于Nginx下, 是不支持PATH INFO的, 也就是它不會(huì)默認(rèn)設(shè)置PATH_INFO.

因此,對(duì)于一個(gè)Nginx架構(gòu)的常規(guī)請(qǐng)求來(lái)說(shuō),這幾個(gè)字段的值分別是:

# http://www.baidu.com:8080/odp/index.php?r=update
PHP_SELF: /odp/index.php
SCRIPT_NAME: /odp/index.php
PATH_INFO: null
問(wèn)題:PHP_SELF中出現(xiàn)重復(fù)路徑

在我部署完成新的Nginx服務(wù)后,得到的上面三個(gè)字段的值為:

# http://www.baidu.com:8080/odp/index.php?r=update
PHP_SELF: /odp/index.php/odp/index.php
SCRIPT_NAME: /odp/index.php
PATH_INFO: /odp/index.php

注意這里的PHP_SELF字段存在重復(fù)的路徑,而PATH_INFO也存在了值,此時(shí)的nginx.conf配置為:

fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;

# 注意這一行,我們配置了PATH_INFO字段
fastcgi_param  PATH_INFO          $fastcgi_script_name;
fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;
fastcgi_param  HTTPS              $https if_not_empty;

fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

那么我們?yōu)槭裁磁渲昧?b>PATH_INFO就會(huì)影響PHP_SELF的值了呢?這一點(diǎn),我們首先會(huì)想到PHP_SELF這個(gè)自定義屬性的來(lái)源是什么,然而,我并沒有找到任何的文檔說(shuō)明。但我們可以通過(guò)重命名的方式,來(lái)探究一下它的定義:

fastcgi_param  PATH_INFO          PATH_INFO;
# fastcgi_param  PATH_INFO          $fastcgi_script_name;

fastcgi_param  SCRIPT_NAME        SCRIPT_NAME;
# fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;

變更這兩行,我們將其重命名為指定字符串,而不是請(qǐng)求傳入的變量,nginx reload后,此時(shí)的結(jié)果是:

# http://www.baidu.com:8080/odp/index.php?r=update
PHP_SELF: SCRIPT_NAMEPATH_INFO
SCRIPT_NAME: SCRIPT_NAME
PATH_INFO: PATH_INFO

而其他變量均正常,因此我們可以進(jìn)一步理解:

PHP_SELF = SCRIPT_NAME + PATH_INFO
自定義變量:PHP_SELF

那么PHP為什么要自定義這個(gè)屬性呢?在官方文檔里有這么一個(gè)url請(qǐng)求,此時(shí):

# http://www.example.com/php/path_info.php/some/stuff?foo=bar 
PHP_SELF: /php/path_info.php/some/stuff
SCRIPT_NAME: /php/path_info.php
PATH_INFO: /some/stuff

所以,在這種場(chǎng)景下,只有PHP_SELF才能拿到完整的當(dāng)前執(zhí)行腳本的文件或路徑。

總結(jié)

為了不同服務(wù)器、不同語(yǔ)言之間的請(qǐng)求通信,于是有了CGI協(xié)議規(guī)范,這個(gè)規(guī)范在不同的服務(wù)器和語(yǔ)言中有自己的實(shí)現(xiàn),在Web Server: Nginx的配置文件中,可以設(shè)置不同變量的值,解析后傳遞給PHP-FPM(PHP-FastCGI Process Manager),再進(jìn)一步傳遞給負(fù)責(zé)響應(yīng)請(qǐng)求的PHP子進(jìn)程,而PHP中也定義了關(guān)于請(qǐng)求通信的全局變量$_SERVER,用于解析請(qǐng)求和處理邏輯。這就是整個(gè)關(guān)于解析請(qǐng)求信息的流程。

由于PHP$_SERVER中的這幾個(gè)變量的定義有一定混淆,也依賴于不同的實(shí)現(xiàn)和Server環(huán)境,如PATH_INFONginx/Apache中的不同默認(rèn)狀態(tài),因此,如果需要頁(yè)面指向自己時(shí),除非如上面示例中的那種url,建議使用SCRIPT_NAME變量即可。

參考資料

segmentfault-php-fpm進(jìn)程數(shù)管理: https://segmentfault.com/a/11...

RFC-CGI1.1: https://tools.ietf.org/html/r...

CGI規(guī)范及其歷史:http://www.voidcn.com/article...

php關(guān)于$_SERVER中一些和環(huán)境有關(guān)的參數(shù)詳解: https://www.jianshu.com/p/fea...

PHP文檔-$_SERVER:http://php.net/manual/zh/rese...

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/30123.html

相關(guān)文章

  • PHP_SELF變量解析重復(fù)路徑解決

    摘要:是通用網(wǎng)管協(xié)議,用于讓交互程序和服務(wù)器通信的協(xié)議。的超全局變量是一個(gè)包含了諸如頭信息路徑以及腳本位置等等信息的數(shù)組。常量包含當(dāng)前例如包含文件的完整路徑和文件名。包含當(dāng)前腳本的路徑。這就是整個(gè)關(guān)于解析請(qǐng)求信息的流程。 最近升級(jí)PHP到PHP7版本,并重新部署了新的Nginx,啟動(dòng)的時(shí)候發(fā)現(xiàn)了一個(gè)問(wèn)題,全局變量$_SERVER[PHP_SELF]的值發(fā)生了改變,從而影響到代碼的功能。因此我...

    weknow619 評(píng)論0 收藏0
  • Phalcon填坑手冊(cè):開發(fā)中會(huì)遇到的問(wèn)題解決方案(不斷更新)

    本文將記錄我在Phalcon開發(fā)過(guò)程中遇到的問(wèn)題,以及如何如何解決。 本文首發(fā)在我的博客,我更新之后會(huì)更新過(guò)來(lái);如果想查看最新的,可以到我的博客:Phalcon填坑手冊(cè):開發(fā)中會(huì)遇到的問(wèn)題和解決方案(不斷更新) 1. 正確地在控制器中獲取參數(shù) 一般情況下,GET/POST請(qǐng)求獲取參數(shù): $this->request->get(參數(shù)名); $this->request->getPost(參數(shù)名) 路...

    sf190404 評(píng)論0 收藏0
  • php超全局變量,魔術(shù)常量,魔術(shù)方法

    摘要:注意和是不同的變量,處理它們的方式不同變量說(shuō)明默認(rèn)情況下包含了,和的數(shù)組。包含相同的信息,但它不是一個(gè)超全局變量。這些特殊的常量不區(qū)分大小寫,如下幾個(gè)的魔術(shù)常量名稱說(shuō)明文件中的當(dāng)前行號(hào)。 整理了下關(guān)于php的基礎(chǔ)知識(shí),參考了些資料,如下: 超全局變量 超全局變量 — 超全局變量是在全部作用域中始終可用的內(nèi)置變量: $GLOBALS $GLOBALS — 引用全局作用域中可用的全部變量 ...

    mj 評(píng)論0 收藏0
  • php查漏補(bǔ)遺

    摘要:變量名獲取該變量的類型名字,返回的是一個(gè)表示該類型名字的字符串,比如,,,變量名,目標(biāo)類型將該變量強(qiáng)制改變?yōu)槟繕?biāo)類型。。。。省略類型系列函數(shù)判斷某個(gè)數(shù)據(jù)是否為某種類型,有如下一些判斷是否是一個(gè)整數(shù)類型判斷是否是一個(gè)數(shù)字判斷是否是一個(gè)標(biāo)量類型 本地運(yùn)行php腳本 運(yùn)行php文件:php.exe -f php文件路徑php.exe -f index.php運(yùn)行php代碼:php.exe...

    bigdevil_s 評(píng)論0 收藏0
  • php超全局變量server

    摘要:元素代碼描述返回當(dāng)前執(zhí)行腳本的文件名。返回服務(wù)器使用的規(guī)范的版本。返回當(dāng)前運(yùn)行腳本所在的服務(wù)器的主機(jī)名比如。返回來(lái)自當(dāng)前請(qǐng)求的請(qǐng)求頭。返回當(dāng)前頁(yè)面的完整不可靠,因?yàn)椴皇撬杏脩舸矶贾С?。是否通過(guò)安全協(xié)議查詢腳本。 元素/代碼 描述 $_SERVER[PHP_SELF] 返回當(dāng)前執(zhí)行腳本的文件名。 $_SERVER[GATEWAY_INTERFACE] 返回服務(wù)器...

    Corwien 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<