Use variable variables with superglobal arrays - php

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'];

Related

Variable Variable for $_GET

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();

global vs $GLOBALS in php

I know it's better to use passing by reference instead of doing this, but i'm wondering why would this code (Code 1) work fine but the other (Code 2) wouldn't ?
Code 1:
<?php
$var = 5;
function unset_var() {
unset($GLOBALS['var']);
}
unset_var();
echo $var; //Notice: Undefined variable: var
?>
Code 2:
<?php
$var = 5;
function unset_var() {
global $var;
unset($var); // trying to unset $var
}
unset_var();
echo $var; // 5
?>
Your second code has a function that creates a new variable and you're unsetting that one, not the one outside the function. Your first code manipulates only the $GLOBALS array.
Also you should avoid even thinking about global variables in the first place....

PHP require_once not working in my code

this is probably a basic question about php, but I can't figure out how to solve it.
Well, I have a file called globals.php
<?php
$DATA = array(
'first' => 'LOL',
'second' => 'Whatever'
);
?>
And I also have another file (omg.php) with the following function:
<?php
require_once('globals.php');
function print_text_omg($selector = 0){
global $DATA; //added this line of code. NOW IT WORKS
$var = '';
if($selector == 0){
$var = '';
}else{
$var = 'Hi. ';
}
//$DATA is a variable from globals.php that is supposed to be declared in require_once('globals.php');
//$var is a variable inside the function print_text_omg
//I am trying to concatenate string $var with the string $DATA['first']
$finaltext = $var.$DATA['first'];
echo $finaltext;
}
?>
Then, in main.php I have this:
<?php
include('omg.php');
print_text_omg();
print_text_omg(1);
?>
This should print something like:
//LOL
//Hi. LOL
Instead, I have this warning:
Notice: Undefined variable: DATA in ...
Which is the part of $finaltext = $var.$DATA['first'];
UPDATE
Thanks to user Casimir et Hippolyte' suggestion, I've edited my function and it works now. Added the line that worked for me.
It doesn't work because $DATA isn't in the scope of your function.
To make $DATA available inside your function, you must pass it as a parameter to the function or define $DATA as a global variable.
The problem isn't related to require_once.
http://php.net/manual/en/language.variables.scope.php
The error is correct, first I can't find where did you declare $var (maybe it should be an object of some class?) and also $var doesn't contain the $DATA array, and for last, . operator in php is for concatenate strings, for object navigation is -> operator
You haven't declared the variable $var, plus . is php's concatenation operator. Try changing your code to this
$finaltext = $DATA['first'];

PHP object properties

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.

PHP 5.4 Anonymous Function in Array undefine

This is PHP 5.4 code...
<?php
function abc($YesNo){return $YesNo["value"];}
$YesNo = array("value"=>"No","text"=>"No");
$x = array("active"=>function(){return abc($YesNo);});
echo $x['active']();
?>
Notice: Undefined variable: YesNo on line 7
Output Should be : Yes
if i directly put array in code by replace $YesNo like
<?php
function abc($YesNo){return $YesNo["value"];}
$x = array("active"=>function(){return abc(array("value"=>"Yes","text"=>"Yes"));});
echo $x['active']();
?>
output : Yes
which is correct output. Now what's the problem in first code. I need that for re-usability
Try this,
You can use use for passing data to a closure.
<?php
function abc($YesNo){return $YesNo["value"];}
$YesNo = array("value"=>"No","text"=>"No");
$x = array("active"=>function() use ($YesNo) {return abc($YesNo);});
echo $x['active']();
?>
You provide your anonymous function with a parameter:
$x = array("active"=>function($param){return abc($param);});
then you call it:
echo $x['active']($YesNo);
You may use the use keyword to make your function aware of an external variable:
$x = array("active"=>function() use ($YesNo) {return abc($YesNo);});
but it would be quite against the idea of reusability, in this case.
The problem is that your variable is not accessible within the function due to Variable Scope.
Because the array is defined outside of the function, it is not by default available inside the function.
There's a couple of solutions
Disclaimer: These are intended to fit within the scope of the question. I understand that they are not necessarily best practice, which would require a larger discussion
First Option:
You can declare the array within the function, like below. This is useful if you don't need access to it outside of the function.
function abc($YesNo){
$YesNo = array("value"=>"No","text"=>"No");
return $YesNo["value"];
}
Second Option:
Within your abc function, you can add the line global $YesNo. This is useful if you do need access to the array outside of the function:
function abc($YesNo){
global $YesNo;
return $YesNo["value"];
}
Other options exist (such as moonwave99's answer).
Finally:
Why are you putting an anonymous function within the array of $x? Seems like a path that will lead to problems down the road....
Your variable $YesNo needs to be visible in the scope of your anonymous function. You need to add global $YesNo as the first statement in that function:
So
$x = array("active"=>function(){return abc($YesNo);});
becomes
$x = array("active"=>function(){global $YesNo; return abc($YesNo);});
... also "value"=>"No" should be "value"=>"Yes" if you want it to return "Yes"

Categories