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,並執行單個檔案上載的程式碼。
如果遇到問題,則執行切換塊,並根據該特定上載的錯誤呈現錯誤。

通過 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

一個關聯陣列,預設包含 $_GET$_POST$_COOKIE 的內容。

正如 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 的詳細資訊,請參閱此答案