When I print $GLOBALS using this code:
<?php print_r($GLOBALS); ?>
I get this output:
Array ( [_GET] => Array ( ) [_POST] => Array ( ) [_COOKIE] => Array ( ) [_FILES] => Array ( ) [GLOBALS] => Array *RECURSION* )
What does "*RECURSION*" mean in this case, and why are $_SERVER, $_REQUEST, etc. not printed as well?
See this part of PHP Manual:
Keep in mind that $GLOBALS is, itself, a global variable. So code like this won't work:
<?php
print '$GLOBALS = ' . var_export($GLOBALS, true) . "\n";
?>
This results in the error message: "Nesting level too deep - recursive dependency?"
You already have retrieved the whole list - you just cannot display part of it (the one containing a recursion, because you would have timeout rather than anything meaningful).
When it comes to $_REQUEST, it is a derivative from $_GET, $_POST and $_COOKIE, so its content is redundant.
EDIT: There is an old bug / feature, that seems to be populating $GLOBALS with $_SERVER and $_REQUEST when they are accessed. So try to access $_REQUEST and hope it helps. Anyway, it can be found in $GLOBALS after that: ideone.com/CGetH
$GLOBALS contains itself as an array. In the PHP reference you can find the definition of $GLOBALS:
An associative array containing references to all variables which are currently defined in the global scope of the script. The variable names are the keys of the array.
Therefore, it has to contain also itself, which leads to a recursion.
The other arrays are probably just empty, since nothing else has happened in your script.
There is an old joke about recursion: "To understand recursion, you must understand recursion".
BTW: It outputs _SERVER on my computer.
Related
I found what appears to be an abusable bug in the PHP language. When creating variable variables a seemingly illegal variable can be declared and then handled as long as you keep accessing it as a variable variable.
Example:
${'0'} = 1; //I am an illegal variable called $0
${'0'}++; //I can be accessed and manipulated.
var_dump(${'0'}); //Output: int(2)
This behavior appears rather odd. It is briefly mentioned in the official documentation for SimpleXml as a way to create variable names that contain hyphens but my example shows it can be abused pretty badly nonetheless.
I would like to know how come this behavior is possible and is tolerated when the code is parsed?
Internally PHP stores variables (zend_array* symbol_table) in a same data structure that is used for arrays. This allows you to have variable names with the same constraints as array keys.
Eg. Zend API function zend_set_local_var sets a value to symbol table using zend_hash_update, which is a function used to manipulate PHP array types as well.
We can't however allow every character in variable names in PHP source code. That's because lexical analysis must distinguish labels from other tokens. Variable variables offer a workaround for this.
It's not a bug nor a way to abuse anything. That being said, the documentation states that all labels, including variables, must have a regex form [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*, so i wouldn't rely on having arbitrary characters in variable names.
What ${'0'} = 1; actually does, it sets value 1 to the current scope's symbol table at key 0.
You can get that particular table with get_defined_vars function.
Looking at the source code, we'll see that the function just copies the current symbol table and returns it to caller.
PHP extract function (src) actually checks that keys have a valid label format (by calling php_valid_var_name), so you can't generate variables with funky names using that.
Anyway, even though it's possible to create variables of any name using variable variable syntax (even a variable with no name ${''}), i think it's bad practice. Even worse if a library expects or enforces you to do so. Saying it's a workaround might be a bit overstatement actually. Maybe it should be considered as an implementation detail and an undocumented feature.
#Nadav I don't have full idea about that but have a little bit idea,
Remember that curly braces({}) literally mean "evaluate what's inside the curly braces" so, you can squeeze the variable creation like you did ${'0'} = 1
reffered it from this http://php.net/manual/en/language.variables.php#73373
PHP stores variable in the array form, if you want to check then use $GLOBALS(an array) is the super global variable which has all the reference of the variables present in the script, it stores variable name as key and value as variable value, suppose below case:
<?php
${'0'} = 1; // here php stores it as 0th index in the array
${'1'} = 2; // here php stores it as 1th index in the array
$b = "I am b"; // here php stores it as bth index in the array
echo "<pre>";
print_r($GLOBALS);
output:
Array
(
[_GET] => Array
(
)
[_POST] => Array
(
)
[_COOKIE] => Array
(
)
[_FILES] => Array
(
)
[GLOBALS] => Array
*RECURSION*
[0] => 1
[1] => 2
[b] => I am b
)
I am learning PHP from w3schools' PHP Tutorial.
While learning PHP I came across the concept of predefined global variables i.e. Superglobals.
In a curiosity to understand "Superglobals" more deeply I wrote the following code and executed it in a browser on my local machine(i.e.localhost) :
<!DOCTYPE html>
<html>
<body>
<?php
echo "<pre>";
print_r($GLOBALS);
echo "</pre>";
?>
</body>
</html>
I got following output in a browser :
Array
(
[_GET] => Array
(
)
[_POST] => Array
(
)
[_COOKIE] => Array
(
[toWorkNormally] => 1
)
[_FILES] => Array
(
)
[GLOBALS] => Array
*RECURSION*
)
The above output has created many doubts in my mind as follows :
As per my knowledge in PHP there are nine types of
superglobals (predefined PHP global variables) viz. $GLOBALS,
$_SERVER, $_REQUEST, $_POST, $_GET, $_FILES, $_ENV, $_COOKIE and
$_SESSION then my doubt is what does the array elements from the predefined global array
$GLOBALS viz. [_GET], [_POST], [_COOKIE], [_FILES] mean as they have
their own independent existence as superglobals?
What is meant by [toWorkNormally] => 1 from above array output?
What does mean by RECURSION in element [GLOBALS] and how to print
those elements?
As the purpose of $GLOBALS array is to store variables declared by user globally then how this array has been pre-populated with some other values as I haven't declared any global variable in my code?
Note : I'm using "Microsoft Windows 10 Home Single Language" operating system on my machine. It's a 64-bit Operating System. I'm using latest edition of XAMPP with PHP 7.0.13 and HTTP Apache web server v.2.4.23 for running the program locally. Also, please note that I have not defined any other variable as global or local in my code.
From my knowledge of PHP and doing some research as well as testing this on multiple OS' with various version of PHP I found the following.
Question 1 & 3:
Yes you are correct with regards to the 9 superglobals, but a very important thing to keep in mind is that $GLOBALS -- References all variables available in global scope.
An interesting sidenote, notice that $GLOBALS is the only superglobal that doesn't start with an underscore.
Because of the fact that $GLOBALS contains references to all the other superglobals including itself, when we print_r($GLOBALS) it will also include the other superglobals in the output. Because $GLOBALS references itself as well we get the RECURSION you asked about in your 3rd point. You can think of it as a infinite dimensional array containing $GLOBALS. Almost the same idea as an infinte loop.
[GLOBALS] => Array
(
[GLOBALS] => Array
(
[GLOBALS] => Array
(
...
)
)
)
Instead the script sees this and stop executing and just prints RECURSION. Now I have tested it on 3 different environments and each time the order in which the superglobals are printed changed, but as soon as it hits $GLOBALS it stops and prints RECURSION.
Question 2:
I could not find any info on $_COOKIE[toWorkNormally] => 1. I am assuming this is set somewhere else. I didn't see it in any of my tests.
Question 4:
This is neither correct nor incorrect. The purpose of $GLOBALS is not to store all variables created by the user globally. It merely references all variables available in global scope including, the superglobals. That is why you are seeing all the other superglobals in the output. But a lot of developers assume that the user defined global variables are stored in $GLOBALS.
Description in the PHP.net manual
An associative array containing references to all variables which are
currently defined in the global scope of the script. The variable
names are the keys of the array.
To view all the superglobals you will have to print_r() each one of them individually.
To check all user defined global variables you can use array_keys($GLOBALS) all the items which are not superglobals will most probably be user defined global variables.
EDIT in response to users comments
In response to your 1st comment, No they are not different. The superglobals not printed are still part of the array but execution/output stops because it hits the RECURSION when it gets to $GLOBALS. The superglobals are printed in a random order and which ever comes after the $GLOBALS will not be seen as it detects a RECURSION at $GLOBALS and stops the output.
You can check all the superglobals/global variables by using print_r(array_keys($GLOBALS)); With an exception of $_SESSION because a session has not been started yet. print_r($_SESSION) will give you an undefined variable $_SESSION Notice. You will be able to see $_SESSION when you put session_start(); just before you print it.
Link to What References Are in PHP
References in PHP are a means to access the same variable content by different names.
Note that in PHP, variable name and variable content are different, so the same content can have different names
The PHP manual says the following about the $GLOBALS variable:
An associative array containing references to all variables which are currently defined in the global scope of the script. The variable names are the keys of the array.
This describes exactly what the variable does. It is simply a reference to existing variables.
The RECURSION you are talking about is the $GLOBALS variable referring to itself. Since we don't want PHP to endlessly output the same output and crashing your server in the process, there is a built-in failsafe that shows you the RECURSION alert if this is the case.
I would like to add that $GLOBALS is a superglobal, or preset global, variable. This means that it is available in all scopes throughout your script.
Resources
The PHP manual about $GLOBALS
$GLOBALS is the global of all super global and user defined variables. So for example if you have declared variable $a = 10; in your $GLOBALS array you have key=>value pair where key is a and value is 10.If you want to get something from $GLOBALS you just need to write it as array key.
example
$a = 25;
echo $GLOBALS['a'];
In the example above output will be the value of $a so 25;
In your example toWorkNormally=>1 it`s mean that you have set cookie with name toWorkNormally and with value 1 or true
Also when you submit form with get or post method in the $GLOBALS['_GET'] or $GLOBALS['_POST'] there you can find your form data as you can get them from super global $_GET or $_POST
1. As per my knowledge in PHP there are nine types of superglobals (predefined PHP global variables) viz. $GLOBALS, $_SERVER, $_REQUEST, $_POST, $_GET, $_FILES, $_ENV, $_COOKIE and $_SESSION then my doubt is what does the array elements from the predefined global array $GLOBALS viz. [_GET], [_POST], [_COOKIE], [_FILES] mean as they have their own independent existence as superglobals?
From PHP's doc:
References all variables available in global scope
This means you can access a superglobal directly or from $GLOBALS, yes, you have two ways of accessing them.
2. What is meant by [toWorkNormally] => 1 from above array output?
It's inside $_COOKIE so there's a cookie named toWorkNormally with the value of 1. More info on cookies
3. What does mean by RECURSION in element [GLOBALS] and how to print those elements?
Recursion means it refereces itself, if it was printed then it would show the contents of $GLOBALS again nested inside GLOBALS, that would cause infinite loop. To avoid that PHP just printed *RECURSION* instead.
4. As the purpose of $GLOBALS array is to store variables declared by user globally then how this array has been pre-populated with some other values as I haven't declared any global variable in my code?
From PHP's doc:
Several predefined variables in PHP are "superglobals", which means they are available in all scopes throughout a script. There is no need to do global $variable; to access them within functions or methods.
So in other words, $GLOBALS will show you those predefined variables from PHP and also the values you set manually.
I have a PHP script that dumps data from an API.
The dump is an array
print_r($answer);
outputs
Array ( [success] => 1 [serial] => s001 [url] => http://gooole.com )
I want to have another variable called $url that holds the value url from the array (held in $answer) in PHP.
I'm unfamiliar with this.
check out extract() it will take the keys from an array, and create variable of the same name to store them in. There are a few flags you can pass it, to determine exactly what it does with things like pre-existing variables of the same name.
EDIT: as mentioned in the comments on your question, though, $url = $answer['url']; is probably the simplest way to go.
I'm learning PHP and Drupal. I need to reference a variable contained in an array called $contexts.
So print_r($contexts) gives me this:
Array (
[context_view_1] => ctools_context Object (
[type] => view
[view] => view Object (
[db_table] => views_view
[result] => Array (
[0] => stdClass Object (
[nid] => 28
[node_data_field_display_field_display_value] => slideshow
)
)
eek confusing. I want to work with the node_data_field_display_field_display_value variable. I think my code needs to be like this, but I know this isn't right:
if ($contexts['context_view_1']['view']['result'][0]
['node_data_field_display_field_display_value'] == 'slideshow') then do whatever...
Thanks!
You suggested the following array reference to get to the variable you want:
$contexts['context_view_1']['view']['result'][0]['node_data_field_display_field_display_value']
The reason this doesn't work is because some of the structures in the chain are actually objects rather than arrays, so you need a different syntax for them to get at their properties.
So the first layer is correct, because $contexts is an array, so context_view_1 is an array element, so you'd get to it with $contexts['context_view_1'] as you did.
But the next level is an object, so to get to view, you need to reference it as an object property with -> syntax, like so: $contexts['context_view_1']->view
For each level down the tree, you need to determine whether it's an object or an array element, and use the correct syntax.
In this case, you'll end up with something that looks like this:
$context['context_view_1']->view->result[0]->node_data_field_display_field_display_value
That's a mess of a variable. The issue you're having is that you're using the bracketed notation, e.g. "['view']", for each "step" in the navigation through your variable. That would be fine if each child of the variable were an array, but not every one is.
You'll note, for example, that $contexts['context_view_1'] is actually an object, not an array (take note that it says "[context_view_1] => ctools_context Object"). Whereas you would use that bracketed notation to address the elements of an array, you use the arrow operator to address the properties of an object.
Thus, you would address the field you are trying to reach with the following expression:
$contexts['context_view_1']->view->result[0]->node_data_field_display_field_display_value
For properties listed as "Object", you need to use -> to get into it, and "Array", you need to use []. So:
$contexts['context_view_1']->view->result[0]->node_data_field_display_field_display_value
$contexts['context_view_1']->view->result[0]->node_data_field_display_field_display_value
echo $context['context_view_1']->view->result[0]->node_data_field_display_field_display_value;
Do not mistake objects with arrays. A memeber of an array can be accesed by $array['member'], but fields of an object can be accessed as $object->fieldname.
Hi can we create two dimensional array using php session. If possible how to unset values randomly.
No, PHP does not implement multi-dimensional arrays. However an element of an array can be an array itself. And any PHP data item can be stored in the session (however resources become meaningless outisde the thread they were initialized in, and objects require class definitions to be referenced from the session).
e.g.
<?php
$two_d=array(
array(1,2,3),
array(4,5,6),
array(7,8,9),
array('#','.','=')
);
$two_d[3][2]='*'; // was '='
how to unset values randomly
This would be an oxymoron in a 2-dimensional array. But is perfectly valid in the context of an array of arrays:
unset($two_d[1]); // removed the whole second row from the above
unset($two_d[0][1]); // $two_d[0] is now array(1,3)
$_SESSION['whateverValue'] = Array(
1 => Array (
'a','b','c','d'
),
2 => Array (
'q','w','e','r','t'
)
);
Voila, a two-dimensional array, in a session.
The session variables are in no way special while the script is executing. Their only "magic" is that they are unserialized at session_start() and serialized at session_close()