php里的全局变量实现,global,$GLOBALS以及$GLOBALS['GLOBALS'] 存疑待解决20188.8.14

版权声明:本文为博主原创文章,未经博主允许不得转载。 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的底层实现。

猜你喜欢

转载自blog.csdn.net/sinat_35880197/article/details/81671931