This question already has an answer here:
I'm using following PHP version on my local machine and running the PHP programs from localhost only.
PHP 5.3.10-1ubuntu3.13 with Suhosin-Patch (cli) (built: Jul 7 2014 18:54:55)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies
I've written a very simple PHP program as follows:
<!DOCTYPE html>
<html>
<body>
<?php
$x = 5;
$y = 10;
print_r($GLOBALS);
die;
function myTest() {
global $x, $y;
$y = $x + $y;
}
myTest(); // Run function
echo $y; // Output the new value for variable $y
?>
</body>
</html>
After executing the above program I'm getting following output in a browser window:
Array ( [GLOBALS] => Array *RECURSION* [_POST] => Array ( ) [_GET] => Array ( ) [_COOKIE] => Array ( ) [_FILES] => Array ( ) [x] => 5 [y] => 10 )
From the above output I'm not getting why the string RECURSION is getting displayed, from where it came. What's the cause behind it?
Also, why is the underscore character appearing at the beginning of all contained arrays**(_POST, _GET, _FILES)**?
</div>
The easiest way to think of it is by imagining how it would have been if *RECURSIVE*
WOULDN'T have been displayed:
Array
(
[GLOBALS] => Array
(
[GLOBALS] = Array
(
[GLOBALS] = Array
(
...
)
...
)
[_POST] => Array ( )
[_GET] => Array ( )
...
)
[_POST] => Array ( )
[_GET] => Array ( )
[_COOKIE] => Array ( )
[_FILES] => Array ( )
[x] => 5
[y] => 10
)
$GLOBALS
contains references to all global variables, and since $GLOBAL
is a global variable itself, it also contains a reference to itself. As you can see, the above will result in a recursive pattern, which never ends, simply because the $GLOBALS
-array contains a reference to itself as an element. This means that printing it with print_r()
would be impossible, since it would result in infinite recursion. Therefore, the print_r()
function solves this by adding the string *RECURSION*
instead. Here's a quote from the PHP-manual:
Prior to PHP 4.0.4, print_r() will continue forever if given an array or object that contains a direct or indirect reference to itself. An example is print_r($GLOBALS) because $GLOBALS is itself a global variable that contains a reference to itself.
This also means that displaying any object which contains recursive references to themselves will lead to this string being displayed. A simple example is:
$a = array(&$a); //$a contains one element with a reference to itself
print_r($a); //prints: Array ( [0] => Array ( [0] => Array *RECURSION* ) )
Although note that this won't hide any info from you - you still know what the GLOBALS
-element contains (the same thing as printed, basically), if having all this in mind.
To answer your second question: The reason the names start with and underscore is simply because several "super-global" variables do so. It makes it easier to distinguish the super-globals from regular variables, and (somewhat) prevents people from using those names by mistake. So when accessing the _POST
-array for instance, you use $_POST
instead of just $POST
, meaning that the element-key in the $GLOBALS
-variable becomes _POST
, as it's the "actual" name of the variable.