php全局变量$_REQUEST,数据来源哪里?有什么潜规则?
发布于 作者:苏南大叔 来源:程序如此灵动~
本文对php的$_REQUEST全局变量进行一下简单的分析。当然,本文依然是一篇颠覆三观的文章,刷新大家对$_REQUEST的认知。在各种高级语言编程里面,request都是在做http编程的时候的首要交互变量。然而,在php编程语言里面,这个$_REQUEST却是不被推荐使用的。这究竟是为什么呢?

苏南大叔的“程序如此灵动”博客,记录苏南大叔的代码感想和感悟。本文测试环境:win10,nginx@1.15.11,php@8.2.10-nts。
$_REQUEST组成
$_REQUEST实际上是由$_GET、$_POST、以及$_COOKIE三者合并而成的。所以,更推荐使用的是后面这三个变量:$_GET、$_POST、以及$_COOKIE。因为它们具有更加明确的指代性。

如果使用$_REQUEST全局变量的话,就必须知晓它的几条潜规则,才能更好的调试和使用$_REQUEST相关的php代码。
request_order合并顺序
在php.ini里面是这样写的:
; request_order
; Default Value: None
; Development Value: "GP"
; Production Value: "GP"; This directive determines which super global data (G,P & C) should be
; registered into the super global array REQUEST. If so, it also determines
; the order in which that data is registered. The values for this directive
; are specified in the same manner as the variables_order directive,
; EXCEPT one. Leaving this value empty will cause PHP to use the value set
; in the variables_order directive. It does not mean it will leave the super
; globals array REQUEST empty.
; Default Value: None
; Development Value: "GP"
; Production Value: "GP"
; https://php.net/request-order
request_order = "GP"苏南大叔的理解就是:$_REQUEST全局变量的数据来源有三个,分别是:$_GET、$_POST、以及$_COOKIE。然而,php官方并不相信$_COOKIE值,默认情况下,并不会开启对$_COOKIE变量的合并,而仅仅处理$_GET、$_POST。
request_order的内存里面的默认值是None,但是实际上默认写在php.ini里面的值是GP。
潜规则一,GPC相互覆盖
如果被合并的三个变量之间有同名成员组成的话,就会产生谁覆盖谁的问题。于是就有了php.ini里面的这个request_order设置。默认写在php.ini里面的设置为GP,意思就是$_POST覆盖$_GET里面的数据,$_COOKIE不参与数据覆盖。
这个GP设定就比较合理,并不建议修改。当post和get同时传输数据的时候,优先解析post里面的数据。
潜规则二,variables_order替代控制
在php.ini里面,如果没有设置request_order项目的话,内存中就会使用默认者None。这个时候,variables_order就会替代request_order,起到同样的作用。如果variables_order也不设置或者设置为空的话,默认值是EGPCS,最终效果是GPC。
虽然variables_order的设置中,多个E和S,但是也确实存在GPC的字样和顺序。既然request_order取值None的话,这里variables_order就越俎代庖,强制设置$_REQUEST变量的数据来源的覆盖顺序。
特别需要注意的是:这种特殊情况下,C也就是$_COOKIE偷偷参与了$_REQUEST变量的数据覆盖。那么,对于variables_order的默认值EGPCS来说,$_REQUEST变量的数据来源,$_COOKIE的优先级反而变得最高。

测试代码
php文件:
echo "variables_order:\r\n";
var_dump(ini_get("variables_order"));
echo "request_order:\r\n";
var_dump(ini_get("request_order"));
echo "\r\n".'$_REQUEST:'."\r\n";
var_dump($_REQUEST);
echo "\r\n".'$_POST:'."\r\n";
var_dump($_POST);
echo "\r\n".'$_GET:'."\r\n";
var_dump($_GET);
echo "\r\n".'$_COOKIE:'."\r\n";
var_dump($_COOKIE);使用wisdom restClient进行测试,

输出:
variables_order:
string(4) "GPCS"
request_order:
string(2) "GP"
$_REQUEST:
array(1) {
["a"]=>
string(4) "post"
}
$_POST:
array(1) {
["a"]=>
string(4) "post"
}
$_GET:
array(1) {
["a"]=>
string(3) "get"
}
$_COOKIE:
array(1) {
["a"]=>
string(6) "cookie"
}
相关文章
- https://newsn.net/say/restclient-wisdom.html
- https://newsn.net/say/restclient-wiztools.html
- https://newsn.net/say/php-sapi-server.html
结束语
本文所描述的这种情况很少见,毕竟很少有人会改动php.ini。只要注意尽量使用$_GET、$_POST、以及$_COOKIE自身,而不使用一个笼统的$_REQUEST变量即可。
更多php经验文章,请点击苏南大叔的博客文章: