i have following code.
$hello = "World";
$test = "hello";
echo $$test;
When I execute this I get as result: World
So far as good
But when I use a reserved variable, for example $_GET it doesn't work.
$test = "_GET";
var_dump($$test);
Here the result is NULL. Is there a way to get values of a reserved variable throught a variable variable?
Superglobals can only be dereferenced by variable variables in the global scope. The fact you can't get it to work seems to indicate that your code is in a function/method. In this case, you can use the $GLOBALS superglobal:
function foo() {
$str = '_GET';
var_dump($GLOBALS[$str]);
}
foo();
Related
As per the PHP documentation on unset() function :
The behavior of unset() inside of a function can vary depending on what type of variable you are attempting to destroy.
If a globalized variable is unset() inside of a function, only the local variable is destroyed. The variable in the calling environment will retain the same value as before unset() was called.
The code example demonstrating above saying is as below :
<?php
function destroy_foo()
{
global $foo;
unset($foo);
}
$foo = 'bar';
destroy_foo();
echo $foo; // o/p is bar
?>
Now my question is why the above behavior is not applicable in following program that I have written?
<?php
function increment_foo()
{
global $foo;
$foo++;
}
$foo = 36;
increment_foo();
echo $foo; // o/p is 37
?>
My doubt is why the behavior is different in above code than the behavior in the code written for unset() function?
In other words, I want to know in first code the unset() functionality remains limited to the local variable inside the function, it doesn't change the value in global scope outside the function but in the code that I have been written the increment functionality changes the value in global variable scope as well. In my code why it's not remaining limited to the local variable inside a function and changing value/affecting the variable outside the function as well?
Thank You.
The reason for this is that using the global keyword will create a local variable referencing the variable in the global scope. Unsetting simply destroys this reference. It's similar to this piece of code:
$foo = 42; // create variable with value
$bar = &$foo; // create reference to $foo
$bar++; // increment $foo via reference
unset($bar); // destroy reference
var_dump($bar); // NULL
var_dump($foo); // 43
Another way to put it is that doing global $foo is just a shorthand for doing $foo = &$GLOBALS['foo'], e.g. the first example can be rewritten to
function increment_foo()
{
$foo = &$GLOBALS['foo'];
$foo++;
unset($foo);
var_dump($foo); // NULL
}
$foo = 42;
increment_foo();
var_dump($foo); // 43
Maybe that makes it more obvious that you are only destroying the reference, e.g. you are destroying what points to $foo, but not $foo itself.
I wonder if is possible to read dynamically superglobal variables, I would like to do something like that:
<?php
$n = 'GET';
$var = '$_'.$n.'[\'something\']'; // pour lire $_GET['something']
echo $var;
//Or
$n = 'POST';
$var = '$_'.$n.'[\'something\']'; // pour lire $_POST['something']
echo $var;
?>
This code don't work as I want, but I would like to know if is workable in PHP?
You can't use variable variables with superglobals, functions or class methods and not with $this.
And a quote from the manual (It's right before the user comments if you search it):
Warning:
Please note that variable variables cannot be used with PHP's Superglobal arrays within functions or class methods. The variable $this is also a special variable that cannot be referenced dynamically.
Thank you is exactelly what I search
But we can't use that into function please?
$n = '_GET';
// don't work => Undefined variable: _GET
function f($n) {
echo ${$n}['a'];
}
f($n);
//work fine
echo ${$n}['a'];
I'm new to OOP in PHP and I find the difference between the following two expressions difficult to understand.
$object->$foo;
$object->foo;
Maybe it's my fault, but I could not find the relevant part in the manual.
The first call $obj->$foo is using a so called variable variable. Check this:
class A {
public $foo = 1;
}
$a = new A();
$foo = 'foo';
// now you can use both
echo $a->$foo;
echo $a->foo;
Follow the manual about variable variables
Well, in order to fully understand the somewhat odd-looking $object->$foo, you should understand two things about PHP:
Variable names
Most of the time variables in PHP are quite straight-forward. They begin with a $ sign, have one [a-zA-Z_] character, and then any amount of [a-z-A-Z0-9_] characters. Examples include:
$var = 'Abcdef';
$_GET = [];
$a1 = 123;
// And so on...
Now, PHP variables can actually be named pretty much anything, as long as the name is, or can be cast to, a scalar type. The way you name a variable with anything is to use curly braces ({}), like this:
${null} = 'It works'; echo ${null};
${false} = 'It works'; echo ${false};
${'!'} = 'It works'; echo ${'!'};
// Slightly weirder...
${(int)trim(' 5 ')} = 'It works'; echo ${5};
${implode(['a','b','c'])} = 'It works'; echo $abc;
Important: Just because you can do this does not mean you should, however. It is mostly just an oddity of PHP that you can do this.
Variable variables
A somewhat convoluted explanation: A variable variable is a variable that is accessed using a variable name.
A much easier way to understand variable variables is to use what we just learning about variable names in PHP. Take this example:
${"abc"} = 'Abc...';
echo $abc;
We create a variable using the string, "abc", which can also be accessed using $abc.
Now, there is no reason (or rule) that says it has to be a string.... it can also be a variable:
$abc = 'Abc...';
$varName = 'abc';
echo ${$varName}; // echo $abc
That is basically a variable variable. "Real" variable variables just do not use the curly braces:
$abc = 'Abc...';
$varName = 'abc';
echo $$varName; // echo $abc
As for the question
In the question the $object->$foo thing is basically just an "object variable variable", if you like
$object = new stdClass;
$object->abc = 'The alphabet!';
$foo = 'abc';
echo $object->$foo;
echo $object->{$foo}; // The same
echo $object->{'abc'}; // The same
Object variable variables can be somewhat useful, but they are rarely necessary. Using an associative array is usually a better choice.
global $user vs $user = $GLOBALS['user']
by using "global $var" to get a global variable, do we get a copy of the global var or get a reference to that global variable?
global $user;
Is $user a copy of global object or is a reference to actual global variable?
Thanks.
by using it with global $var; you always have a local variable that references the global variable.
Following code:
$var = 1;
function test() {
global $var;
$var++;
}
test();
echo $var;
is equivalent to:
$var = 1;
function test() {
$GLOBALS['var']++;
}
test();
echo $var;
By using global $var the global variable named "var" will be imported into the local scope of the function (that is done by creating a reference).
That is different to $GLOBALS which is a superglobal variable. That is always everywhere regardless of the scope.
However that's different to references. If you really want to understand about the variables and how this is with references to variables, I suggest the PDF by Derick Rethans: References in PHP: An In-Depth Look (PDF).
Quoting $GLOBALS' documentation:
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.
A simple test case:
$foo = "foo";
echo $GLOBALS["foo"]; // foo
echo $GLOBALS["foo"] = "bar"; // bar
echo $foo; // bar
Neither. The compiler resolves usage of that variable name to the corresponding variable in global scope.
I was trying to pass a variable that contained the name of the superglobal array I wanted a function to process, but I couldn't get it to work, it would just claim the variable in question didn't exist and return null.
I've simplified my test case down to the following code:
function accessSession ($sessName)
{
var_dump ($$sessName);
}
$sessName = '_SERVER';
var_dump ($$sessName);
accessSession ($sessName);
The var_dump outside of the function returns the contents of $_SERVER, as expected. However, the var_dump in the function triggers the error mentioned above.
Adding global $_SERVER to the function didn't make the error go away, but assigning $_SERVER to another variable and making that variable global did work (see below)
function accessSession ($sessName)
{
global $test;
var_dump ($$sessName);
}
$test = $_SERVER;
$sessName = 'test';
var_dump ($$sessName);
accessSession ($sessName);
Is this a PHP bug, or am I just doing something wrong?
PHP: Variable variables - Manual
Warning
Please note that variable variables cannot be used with PHP's Superglobal arrays within functions or class methods. The variable $this is also a special variable that cannot be referenced dynamically.
Solutions
function access_global_v1 ($var) {
global $$var;
var_dump ($$var);
}
function access_global_v2 ($var) {
var_dump ($GLOBALS[$var]);
}
$test = 123;
access_global_v1 ('_SERVER');
access_global_v2 ('test');
From php.net:
Warning
Please note that variable variables cannot be used with PHP's
Superglobal arrays within functions or class methods. The variable
$this is also a special variable that cannot be referenced
dynamically.
The answer is fairly simple: never use variable variables.
Use arrays instead.
(and yes - you are doing something wrong. No, it is not a bug in PHP.)
Use $GLOBALS. There you go :)
<?php
function accessSession ($sessName)
{
var_dump ($GLOBALS[$sessName]);
}
$sessName = '_SERVER';
accessSession ($sessName);