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