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 的详细信息,请参阅此答案