版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_35880197/article/details/81671931
今天面试,有一道题涉及全局变量的实现,回来查询资料,整理如下;
我们都知道php底层的数组是hashtable实现的,也就是维护了一个$GLOBALS的全局数组变量,现在让我们打印下,看里面都有些什么; (先定义了$a)
<?php
$a = "im a!";
var_dump($GLOBALS);
结果如下:
C:\wamp64\www\xss\test.php:12:
array (size=9)
'_GET' =>
array (size=0)
empty
'_POST' =>
array (size=0)
empty
'_COOKIE' =>
array (size=1)
'_ga' => string 'GA1.1.300902675.1528005070' (length=26)
'_FILES' =>
array (size=0)
empty
'_ENV' =>
array (size=0)
empty
'_REQUEST' =>
array (size=0)
empty
'_SERVER' =>
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/63.0.3239.132 Safari/537.36' (length=110)
'HTTP_ACCEPT' => string 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8' (length=85)
'HTTP_ACCEPT_ENCODING' => string 'gzip, deflate, br' (length=17)
'HTTP_ACCEPT_LANGUAGE' => string 'zh-CN,zh;q=0.9' (length=14)
'HTTP_COOKIE' => string '_ga=GA1.1.300902675.1528005070' (length=30)
'PATH' => string 'C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files\dotnet\;C:\Program Files\Microsoft SQL Server\130\Tools\Binn\;C:\Program Files\nodejs\;C:\wamp64\bin\mysql2\mysql5.7.9\bin;C:\wamp64\bin\php\php7.0.0;C:\ProgramData\ComposerSetup\bin;C:\WINDOWS\system32\config\systemprofile\AppData\Local\Microsoft\WindowsApps' (length=356)
'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' (length=53)
'WINDIR' => string 'C:\WINDOWS' (length=10)
'SERVER_SIGNATURE' => string '<address>Apache/2.4.17 (Win64) PHP/5.6.16 Server at localhost Port 80</address>
' (length=80)
'SERVER_SOFTWARE' => string 'Apache/2.4.17 (Win64) PHP/5.6.16' (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=14)
'REQUEST_SCHEME' => string 'http' (length=4)
'CONTEXT_PREFIX' => string '' (length=0)
'CONTEXT_DOCUMENT_ROOT' => string 'C:/wamp64/www/' (length=14)
'SERVER_ADMIN' => string '[email protected]' (length=17)
'SCRIPT_FILENAME' => string 'C:/wamp64/www/xss/test.php' (length=26)
'REMOTE_PORT' => string '54392' (length=5)
'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 '/xss/test.php' (length=13)
'SCRIPT_NAME' => string '/xss/test.php' (length=13)
'PHP_SELF' => string '/xss/test.php' (length=13)
'REQUEST_TIME_FLOAT' => float 1534241193.719
'REQUEST_TIME' => int 1534241193
'GLOBALS' =>
&array< 'a' => string 'im a!' (length=5)
可以看到变量$a在$GLOBALS['GLOBALS']里面,那我们在函数内调用全局变量$a,除了global修饰符以外,就要使用$GLOBALS['GLOBALS']['a'],那为何我们是使用$GLOBALS['a']呢?
现在我们打印下$GLOBALS['GLOBALS']与$GLOBALS;
var_dump($GLOBALS['GLOBALS'] === $GLOBALS);
结果如下:
C:\wamp64\www\xss\test.php:13:boolean true
也就是说$GLOBALS['GLOBALS']储存的是$GLOBALS的引用地址,这就是为什么$GLOBALS['a'] 等于$GLOBALS['GLOBALS']['a'];
我们再来验证一下:尝试打印$GLOBALS['GLOBALS']['_SERVER'];
var_dump($GLOBALS['GLOBALS']['_SERVER']);
结果如下:
C:\wamp64\www\xss\test.php:14:
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/63.0.3239.132 Safari/537.36' (length=110)
'HTTP_ACCEPT' => string 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8' (length=85)
'HTTP_ACCEPT_ENCODING' => string 'gzip, deflate, br' (length=17)
'HTTP_ACCEPT_LANGUAGE' => string 'zh-CN,zh;q=0.9' (length=14)
'HTTP_COOKIE' => string '_ga=GA1.1.300902675.1528005070' (length=30)
'PATH' => string 'C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files\dotnet\;C:\Program Files\Microsoft SQL Server\130\Tools\Binn\;C:\Program Files\nodejs\;C:\wamp64\bin\mysql2\mysql5.7.9\bin;C:\wamp64\bin\php\php7.0.0;C:\ProgramData\ComposerSetup\bin;C:\WINDOWS\system32\config\systemprofile\AppData\Local\Microsoft\WindowsApps' (length=356)
'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' (length=53)
'WINDIR' => string 'C:\WINDOWS' (length=10)
'SERVER_SIGNATURE' => string '<address>Apache/2.4.17 (Win64) PHP/5.6.16 Server at localhost Port 80</address>
' (length=80)
'SERVER_SOFTWARE' => string 'Apache/2.4.17 (Win64) PHP/5.6.16' (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=14)
'REQUEST_SCHEME' => string 'http' (length=4)
'CONTEXT_PREFIX' => string '' (length=0)
'CONTEXT_DOCUMENT_ROOT' => string 'C:/wamp64/www/' (length=14)
'SERVER_ADMIN' => string '[email protected]' (length=17)
'SCRIPT_FILENAME' => string 'C:/wamp64/www/xss/test.php' (length=26)
'REMOTE_PORT' => string '54392' (length=5)
'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 '/xss/test.php' (length=13)
'SCRIPT_NAME' => string '/xss/test.php' (length=13)
'PHP_SELF' => string '/xss/test.php' (length=13)
'REQUEST_TIME_FLOAT' => float 1534241193.719
'REQUEST_TIME' => int 1534241193
是的,没错,$GLOBALS['GLOBALS']['_SERVER']等于$GLOBALS['_SERVER'],我们上述的猜测是正确的,那具体是怎么实现的呢?
我们现在自己构造一个多维数组,
ps:我自己构造了一个数组,能实现上述,单不够优雅,容我仔细看看php7的底层实现。