Suberglobals 解釋說
介紹
簡而言之,這些是指令碼中所有範圍都可用的變數。
這意味著不需要將它們作為函式中的引數傳遞,也不需要將它們儲存在程式碼塊之外,以使它們在不同的範圍內可用。
什麼是超全域性?
如果你認為這些就像超級英雄 - 他們不是。
從 PHP 7.1.3 版開始,有 9 個超全域性變數。它們如下:
$GLOBALS
- 引用全域性範圍內可用的所有變數$_SERVER
- 伺服器和執行環境資訊$_GET
- HTTP GET 變數$_POST
- HTTP POST 變數$_FILES
- HTTP 檔案上傳變數$_COOKIE
- HTTP Cookies$_SESSION
- 會話變數$_REQUEST
- HTTP 請求變數$_ENV
- 環境變數
請參閱文件 。
告訴我更多,告訴我更多
對於油脂參考我很抱歉! 連結
是時候對這些超級 英雄 全域性的一些解釋了。
$GLOBALS
一個關聯陣列,包含對當前在指令碼全域性範圍內定義的所有變數的引用。變數名是陣列的鍵。
碼
$myGlobal = "global"; // declare variable outside of scope
function test()
{
$myLocal = "local"; // declare variable inside of scope
// both variables are printed
var_dump($myLocal);
var_dump($GLOBALS["myGlobal"]);
}
test(); // run function
// only $myGlobal is printed since $myLocal is not globally scoped
var_dump($myLocal);
var_dump($myGlobal);
輸出
string 'local' (length=5)
string 'global' (length=6)
null
string 'global' (length=6)
在上面的示例中,第二次不顯示 $myLocal
,因為它在 test()
函式內宣告,然後在函式關閉後被銷燬。
成為全域性性的
要解決這個問題,有兩種選擇。
選項一: global
關鍵字
function test()
{
global $myLocal;
$myLocal = "local";
var_dump($myLocal);
var_dump($GLOBALS["myGlobal"]);
}
global
關鍵字是變數的字首,強制它成為全域性範圍的一部分。
請注意,你不能在與 global 關鍵字相同的語句中為變數賦值。因此,為什麼我必須在下面分配一個值。 (如果你刪除新的行和空格是可能的,但我不認為它是整潔的 .global $myLocal; $myLocal = "local"
)。
方案二: $GLOBALS
陣列
function test()
{
$GLOBALS["myLocal"] = "local";
$myLocal = $GLOBALS["myLocal"];
var_dump($myLocal);
var_dump($GLOBALS["myGlobal"]);
}
在這個例子中,我重新分配了 $myLocal
的值,因為我發現更容易編寫變數名而不是關聯陣列。
$_SERVER
$ _SERVER 是一個包含標題,路徑和指令碼位置等資訊的陣列。此陣列中的條目由 Web 伺服器建立。無法保證每個 Web 伺服器都能提供這些服務; 伺服器可能省略一些,或提供此處未列出的其他伺服器。也就是說, CGI / 1.1 規範中考慮了大量這些變數,因此你應該能夠期待這些變數。
此示例的輸出可能如下(使用 WAMP 在我的 Windows PC 上執行)
C:\wamp64\www\test.php:2:
array (size=36)
'HTTP_HOST' => string 'localhost' (length=9)
'HTTP_CONNECTION' => string 'keep-alive' (length=10)
'HTTP_CACHE_CONTROL' => string 'max-age=0' (length=9)
'HTTP_UPGRADE_INSECURE_REQUESTS' => string '1' (length=1)
'HTTP_USER_AGENT' => string 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36' (length=110)
'HTTP_ACCEPT' => string 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' (length=74)
'HTTP_ACCEPT_ENCODING' => string 'gzip, deflate, sdch, br' (length=23)
'HTTP_ACCEPT_LANGUAGE' => string 'en-US,en;q=0.8,en-GB;q=0.6' (length=26)
'HTTP_COOKIE' => string 'PHPSESSID=0gslnvgsci371ete9hg7k9ivc6' (length=36)
'PATH' => string 'C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files (x86)\Intel\iCLS Client\;C:\Program Files\Intel\iCLS Client\;C:\ProgramData\Oracle\Java\javapath;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;E:\Program Files\ATI Technologies\ATI.ACE\Core-Static;E:\Program Files\AMD\ATI.ACE\Core-Static;C:\Program Files (x86)\AMD\ATI.ACE\Core-Static;C:\Program Files (x86)\ATI Technologies\ATI.ACE\Core-Static;C:\Program Files\Intel\Intel(R) Managemen'... (length=1169)
'SystemRoot' => string 'C:\WINDOWS' (length=10)
'COMSPEC' => string 'C:\WINDOWS\system32\cmd.exe' (length=27)
'PATHEXT' => string '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.PY' (length=57)
'WINDIR' => string 'C:\WINDOWS' (length=10)
'SERVER_SIGNATURE' => string '<address>Apache/2.4.23 (Win64) PHP/7.0.10 Server at localhost Port 80</address>' (length=80)
'SERVER_SOFTWARE' => string 'Apache/2.4.23 (Win64) PHP/7.0.10' (length=32)
'SERVER_NAME' => string 'localhost' (length=9)
'SERVER_ADDR' => string '::1' (length=3)
'SERVER_PORT' => string '80' (length=2)
'REMOTE_ADDR' => string '::1' (length=3)
'DOCUMENT_ROOT' => string 'C:/wamp64/www' (length=13)
'REQUEST_SCHEME' => string 'http' (length=4)
'CONTEXT_PREFIX' => string '' (length=0)
'CONTEXT_DOCUMENT_ROOT' => string 'C:/wamp64/www' (length=13)
'SERVER_ADMIN' => string 'wampserver@wampserver.invalid' (length=29)
'SCRIPT_FILENAME' => string 'C:/wamp64/www/test.php' (length=26)
'REMOTE_PORT' => string '5359' (length=4)
'GATEWAY_INTERFACE' => string 'CGI/1.1' (length=7)
'SERVER_PROTOCOL' => string 'HTTP/1.1' (length=8)
'REQUEST_METHOD' => string 'GET' (length=3)
'QUERY_STRING' => string '' (length=0)
'REQUEST_URI' => string '/test.php' (length=13)
'SCRIPT_NAME' => string '/test.php' (length=13)
'PHP_SELF' => string '/test.php' (length=13)
'REQUEST_TIME_FLOAT' => float 1491068771.413
'REQUEST_TIME' => int 1491068771
那裡有很多內容,所以我將在下面挑選一些重要內容。如果你想閱讀所有內容,請參閱文件的索引部分 。
我可能會在一天之內新增它們。或者有人可以編輯並在下面新增一個很好的解釋?提示,提示 ;)
對於下面的所有解釋,假設 URL 為 http://www.example.com/index.php
HTTP_HOST
- 主機地址。
這將返回www.example.com
HTTP_USER_AGENT
- 使用者代理的內容。這是一個字串,其中包含有關客戶端瀏覽器的所有資訊,包括作業系統。HTTP_COOKIE
- 串聯字串中的所有 cookie,帶有分號分隔符。SERVER_ADDR
- 當前指令碼正在執行的伺服器的 IP 地址。
這將返回93.184.216.34
PHP_SELF
- 當前執行指令碼的檔名,相對於文件根目錄。
這將返回/index.php
REQUEST_TIME_FLOAT
- 請求開始的時間戳,精確到微秒。從 PHP 5.4.0 開始提供。REQUEST_TIME
- 請求開始的時間戳。從 PHP 5.1.0 開始提供。
$_GET
通過 URL 引數傳遞給當前指令碼的關聯變數陣列。
$_GET
是一個包含所有 URL 引數的陣列; 這些是什麼之後的?在 URL 中。
以 http://www.example.com/index.php?myVar=myVal 為例。來自此 URL 的資訊可以通過以此格式訪問 $_GET["myVar"]
獲得,其結果將是 myVal
。
為那些不喜歡閱讀的人使用一些程式碼。
// URL = http://www.example.com/index.php?myVar=myVal
echo $_GET["myVar"] == "myVal" ? "true" : "false"; // returns "true"
上面的例子使用了三元運算子 。
這顯示瞭如何使用 $_GET
超全域性訪問 URL 中的值。
現在又一個例子! 喘氣
// URL = http://www.example.com/index.php?myVar=myVal&myVar2=myVal2
echo $_GET["myVar"]; // returns "myVal"
echo $_GET["myVar2"]; // returns "myVal2"
可以通過 URL 將多個變數與&符號(&
)分開來傳送多個變數。
安全風險
通過 URL 傳送任何敏感資訊非常重要,因為它將保留在計算機的歷史記錄中,任何可以訪問該瀏覽器的人都可以看到。
$_POST
當使用 application / x-www-form-urlencoded 或 multipart / form-data 作為請求中的 HTTP Content-Type 時,通過 HTTP POST 方法傳遞給當前指令碼的關聯變數陣列。
與 $_GET
非常相似,因為資料從一個地方傳送到另一個地方。
我將從直接進入一個例子開始。 (我省略了 action 屬性,因為這會將資訊傳送到表單所在的頁面)。
<form method="POST">
<input type="text" name="myVar" value="myVal" />
<input type="submit" name="submit" value="Submit" />
</form>
以上是可以傳送資料的基本表單。在真實環境中,不會設定 value
屬性,這意味著表單將為空白。然後,這將傳送使用者輸入的任何資訊。
echo $_POST["myVar"]); // returns "myVal"
安全風險
通過 POST 傳送資料也不安全。使用 HTTPS 將確保資料更安全。
$_FILES
通過 HTTP POST 方法上載到當前指令碼的關聯專案陣列。 POST 方法上傳部分概述了此陣列的結構。
讓我們從一個基本形式開始。
<form method="POST" enctype="multipart/form-data">
<input type="file" name="myVar" />
<input type="submit" name="Submit" />
</form>
請注意,我省略了 action
屬性(再次!)。另外,我新增了 enctype="multipart/form-data"
,這對於處理檔案上傳的任何形式都很重要。
// ensure there isn't an error
if ($_FILES["myVar"]["error"] == UPLOAD_ERR_OK)
{
$folderLocation = "myFiles"; // a relative path. (could be "path/to/file" for example)
// if the folder doesn't exist then make it
if (!file_exists($folderLocation)) mkdir($folderLocation);
// move the file into the folder
move_uploaded_file($_FILES["myVar"]["tmp_name"], "$folderLocation/" . basename($_FILES["myVar"]["name"]));
}
這用於上傳一個檔案。有時你可能希望上傳多個檔案。存在一個屬性,它叫做 multiple
。
幾乎任何東西都有一個屬性。 對不起
以下是提交多個檔案的表單示例。
<form method="POST" enctype="multipart/form-data">
<input type="file" name="myVar[]" multiple="multiple" />
<input type="submit" name="Submit" />
</form>
請注意這裡所做的更改; 只有少數。
input
名稱有方括號。這是因為它現在是一個檔案陣列,因此我們告訴表單建立所選檔案的陣列。省略方括號將導致後者大多數檔案被設定為$_FILES["myVar"]
。multiple="multiple"
屬性。這只是告訴瀏覽器使用者可以選擇多個檔案。
$total = isset($_FILES["myVar"]) ? count($_FILES["myVar"]["name"]) : 0; // count how many files were sent
// iterate over each of the files
for ($i = 0; $i < $total; $i++)
{
// there isn't an error
if ($_FILES["myVar"]["error"][$i] == UPLOAD_ERR_OK)
{
$folderLocation = "myFiles"; // a relative path. (could be "path/to/file" for example)
// if the folder doesn't exist then make it
if (!file_exists($folderLocation)) mkdir($folderLocation);
// move the file into the folder
move_uploaded_file($_FILES["myVar"]["tmp_name"][$i], "$folderLocation/" . basename($_FILES["myVar"]["name"][$i]));
}
// else report the error
else switch ($_FILES["myVar"]["error"][$i])
{
case UPLOAD_ERR_INI_SIZE:
echo "Value: 1; The uploaded file exceeds the upload_max_filesize directive in php.ini.";
break;
case UPLOAD_ERR_FORM_SIZE:
echo "Value: 2; The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.";
break;
case UPLOAD_ERR_PARTIAL:
echo "Value: 3; The uploaded file was only partially uploaded.";
break;
case UPLOAD_ERR_NO_FILE:
echo "Value: 4; No file was uploaded.";
break;
case UPLOAD_ERR_NO_TMP_DIR:
echo "Value: 6; Missing a temporary folder. Introduced in PHP 5.0.3.";
break;
case UPLOAD_ERR_CANT_WRITE:
echo "Value: 7; Failed to write file to disk. Introduced in PHP 5.1.0.";
break;
case UPLOAD_ERR_EXTENSION:
echo "Value: 8; A PHP extension stopped the file upload. PHP does not provide a way to ascertain which extension caused the file upload to stop; examining the list of loaded extensions with phpinfo() may help. Introduced in PHP 5.2.0.";
break;
default:
echo "An unknown error has occured.";
break;
}
}
這是一個非常簡單的示例,不處理諸如不允許的副檔名或使用 PHP 程式碼命名的檔案(如 SQL 注入的 PHP 等效檔案)之類的問題。請參閱文件 。
第一個過程是檢查是否有檔案,如果是,請將它們的總數設定為 $total
。
使用 for 迴圈允許迭代 $_FILES
陣列並一次訪問一個專案。如果該檔案沒有遇到問題,則 if 語句為 true,並執行單個檔案上載的程式碼。
如果遇到問題,則執行切換塊,並根據該特定上載的錯誤呈現錯誤。
$_COOKIE
通過 HTTP Cookie 傳遞給當前指令碼的關聯變數陣列。
Cookie 是包含資料的變數,儲存在客戶端的計算機上。
與上述超全域性不同,必須使用函式建立 cookie(而不是賦值)。公約如下。
setcookie("myVar", "myVal", time() + 3600);
在這個例子中,為 cookie 指定了一個名稱(在這個例子中它是 myVar
),給出了一個值(在這個例子中它是 myVal
,但是可以傳遞一個變數來將其值賦給 cookie),然後給出一個到期時間(在這個例子中,它是一個小時,因為 3600 秒是一分鐘)。
儘管建立 cookie 的慣例不同,但它的訪問方式與其他 cookie 相同。
echo $_COOKIE["myVar"]; // returns "myVal"
要銷燬 cookie,必須再次呼叫 setcookie
,但過期時間設定為過去的任何時間。見下文。
setcookie("myVar", "", time() - 1);
var_dump($_COOKIE["myVar"]); // returns null
這將取消設定 cookie 並將其從客戶端計算機中刪除。
$_SESSION
包含當前指令碼可用的會話變數的關聯陣列。有關如何使用它的更多資訊,請參閱會話功能文件。
會話很像 cookie,除非它們是伺服器端。
要使用會話,必須在指令碼頂部包含 session_start()
以允許使用會話。
設定會話變數與設定任何其他變數相同。見下面的例子。
$_SESSION["myVar"] = "myVal";
在啟動會話時,隨機 ID 被設定為 cookie 並稱為 PHPSESSID
,並將包含該當前會話的會話 ID。這可以通過呼叫 session_id()
函式來訪問。
可以使用 unset
函式銷燬會話變數(這樣 unset($_SESSION["myVar"])
會破壞該變數)。
另一種方法是呼叫 session_destory()
。這將破壞整個會話,這意味著所有會話變數將不再存在。
$_REQUEST
正如 PHP 文件所述,這只是一個變數中 $_GET
,$_POST
和 $_COOKIE
的整理。
由於所有這三個陣列都可能具有相同名稱的索引,因此 php.ini
檔案中有一個名為 request_order
的設定,它可以指定三個陣列中的哪一個具有優先權。
例如,如果設定為 GPC
,那麼將使用 $_COOKIE
的值,因為它從左到右讀取意味著 $_REQUEST
將其值設定為 $_GET
,然後 $_POST
,然後 $_COOKIE
,因為 $_COOKIE
是最後一個,這是 $_REQUEST
中的值。
看到這個問題 。
$_ENV
通過環境方法傳遞給當前指令碼的關聯變數陣列。
這些變數從執行 PHP 解析器的環境匯入到 PHP 的全域性名稱空間中。許多是由執行 PHP 的 shell 提供的,不同的系統可能執行不同型別的 shell,不可能有明確的列表。有關已定義環境變數的列表,請參閱 shell 的文件。
其他環境變數包括 CGI 變數,無論 PHP 是作為伺服器模組還是 CGI 處理器執行,都放在那裡。
儲存在 $_ENV
中的任何內容都來自執行 PHP 的環境。
$_ENV
僅在 php.ini
允許的情況下才會填充。
有關為何未填充 $_ENV
的詳細資訊,請參閱此答案 。