I'm trying to do a variable variable, but it wont work when I use it in the code below.
I keep getting:
Notice: Undefined variable: C in C:\web\apache\htdocs\cats-test.php on line 8
This only wont work when used with an array. Can you help?
$Consumer = array(
"a" => "Apparel",
"b" => "Books & Stationary",
);
$cat = "Consumer";
echo $$cat['a']; //I'm trying to make this $Consumer['a'];
echo ${$cat}['a'];
It's ambiguous whether you mean $$cat ['a'] or $ $cat['a']. Use brackets.
Be aware of operator priorities. ${$cat}['a'] should work better.
When accessing an array key in a variable variable, enclose the variable in {} to be certain that PHP expands the correct set of characters ($cat) as a variable.
echo ${$cat}['a'];
// Apparel
Related
So variable variables are existing. Meaning that this is working
$a = 'test';
$$a = 'Hello';
echo ${'test'}; //outputs 'Hello'
But now I've come across some rather strange code using a variable without a name:
function test(&$numRows) {
$numRows = 5;
echo ' -- done test';
}
$value = 0;
test($value);
echo ' -- result is '.$value;
test(${''}); //variable without name
http://ideone.com/gTvayV Code fiddle
Output of this is:
-- done test -- result is 5 -- done test
That means, the code is not crashing.
Now my question is: what exactly happens if $numRows value is changed when the parameter is a variable without name? Will the value be written into nirvana? Is that the PHP variable equivalent to /dev/null?
I wasn't able to find anything specific about this.
Thanks in advance
${''} is a valid variable which name happens to be an empty string. If you have never set it before, it is undefined.
var_dump(isset(${''})); // if you have never set it before, it is undefined.
You don't see any error because you disabled the NOTICE error message.
error_reporting(E_ALL);
ini_set('display_errors', 1);
echo ${''}; // Notice: Undefined variable:
You can set it like this:
${''} = 10;
echo ${''}; // shows 10
Now my question is: what exactly happens if $numRows value is changed
when the parameter is a variable without name?
There's no such thing as a variable without name, an empty string in PHP is a totally valid name.
Maybe I'm wrong, but in PHP, all varibles can be accessed by their names (or more precisely, the string representation of their name), and since an empty string is still a string, it counts as a valid name.
Think about variables like an array key-value pair. You can create an array key with an empty string:
$arr = [];
$arr[''] = 'appul';
var_dump($arr['']); // prints: string(5) "appul"
$arr[''] = 'ponka';
var_dump($arr['']); // prints: string(5) "ponka"
Whenever you access $arr[''], you address the same value.
You can access all variables as a string using the $GLOBAL variable too, so you can examine what happens to your "nameless" variable:
${''} = 'ponka';
var_dump($GLOBALS['']); // prints: string(5) "ponka"
${''} = 'appul';
var_dump($GLOBALS['']); // prints: string(5) "appul"
Will the value be written into nirvana? Is that the PHP variable equivalent to /dev/null? I wasn't able to find anything specific about this.
No, it doesn't go to nirvana, it sits quietly in the global space, and it's a little bit trickier to access it, but otherways, it's a normal variable like any others.
I'm not even sure if what I am trying to do is possible, I have a simple php echo line as below..
<?php echo $T1R[0]['Site']; ?>
This works well but I want to make the "1" in the $T1R to be fluid, is it possible to do something like ..
<?php echo $T + '$row_ColNumC['ColNaumNo']' + R[0]['Site']; ?>
Where the 1 is replaced with the content of ColNaumNo i.e. the returned result might be..
<?php echo $T32R[0]['Site']; ?>
It is possible in PHP. The concept is called "variable variables".
The idea is simple: you generate the variable name you want to use and store it in another variable:
$name = 'T'.$row_ColNumC['ColNaumNo'].'R';
Pay attention to the string concatenation operator. PHP uses a dot (.) for this, not the plus sign (+).
If the value of $row_ColNumc['ColNaumNo'] is 32 then the value stored in variable $name is 'T32R';
You can then prepend the variable $name with an extra $ to use it as the name of another variable (indirection). The code echo($$name); prints the content of variable $T32R (if any).
If the variable $T32R stores an array then the syntax $$name[0] is ambiguous and the parser needs a hint to interpret it. It is well explained in the documentation page (of the variable variables):
In order to use variable variables with arrays, you have to resolve an ambiguity problem. That is, if you write $$a[1] then the parser needs to know if you meant to use $a[1] as a variable, or if you wanted $$a as the variable and then the [1] index from that variable. The syntax for resolving this ambiguity is: ${$a[1]} for the first case and ${$a}[1] for the second.
You can do like this
$T1R[0]['Site'] = "test";
$c = 1;
$a = "T".$c."R";
$b = $$a;
echo "<pre>";
print_r($b[0]['Site']);
Or more simpler like this
$T1R[0]['Site'] = "test";
$c = 1;
$a = "T".$c."R";
echo "<pre>";
print_r(${$a}[0]['Site']);
This works with simple variables. But it shows empty result with complex variables. AM I MISSING SOMETHING HERE? or is there anyother way around. Thanks.
#1. This works with simple variables.
$object = "fruit";
$fruit = "banana";
echo $$object; // <------------ WORKS :outputs "banana".
echo "\n";
echo ${"fruit"}; // <------------ This outputs "banana".
#2. With complex structure it doesn't. am I missing something here?
echo "\n";
$result = array("node"=> (object)array("id"=>10, "home"=>"earth", ), "count"=>10, "and_so_on"=>true, );
#var_dump($result);
$path = "result['node']->id";
echo "\n";
echo $$path; // <---------- This outputs to blank. Should output "10".
Not exactly using variable variables, but if you want to use a variable as the var name, eval should work
$path = "result['node']->id";
eval("echo $".$path.";");
From php.net's page on variable variables
A variable variable takes the value of a variable and treats that as the name of a variable.
The issue is that result['node']->id is not a variable. result is the variable. If you turn on error reporting for PHP notices you will see the following in your output:
PHP Notice: Undefined variable: result['node']->id ...
This can be solved as follows:
$path = "result";
echo "\n";
echo ${$path}['node']->id;
The curly braces around $path are required.
In order to use variable variables with arrays, you have to resolve an
ambiguity problem. That is, if you write $$a[1] then the parser needs
to know if you meant to use $a[1] as a variable, or if you wanted $$a
as the variable and then the [1] index from that variable. The syntax
for resolving this ambiguity is: ${$a[1]} for the first case and
${$a}[1] for the second.
If not present the statement is equivalent to
${$path['node']->id}
which will result in the following output:
PHP Warning: Illegal string offset 'node' in /var/www/html/variable.php on line 18
PHP Notice: Undefined variable: r in /var/www/html/variable.php on line 18
PHP Notice: Trying to get property of non-object in /var/www/html/variable.php on line 18
I'm trying to extract values from an array, and pass them to a function where they'll be used. I've used echo inside the function for this example.
I'm using extract to get all the values.
Thing is, this wont work. Do you see how this can be done?
<?php
$my_array = array("a" => "Prince", "b" => "Funky"); // around 10 more
$g = extract($my_array);
foo($g);
function foo($g) {
echo 'My name is '.$a.', and I am '.$b;
}
?>
Functions in PHP have a different scope, so the variables $a, $b etc. aren't available inside your function. Trying to use them inside the function would result in Undefined variable notices (if you enable error reporting, that is).
Right now, you're storing the return value of extract() (which is the total number of variables parsed) into your function. You want the values instead, so change your function like so:
function foo($array) {
extract($array);
echo 'My name is '.$a.', and I am '.$b;
}
Note that I've moved the extract() call inside the function. This way, you wouldn't pollute the global scope with random variables (which may have undesired results and will make your debugging hard for no reason).
Now you can call your function, like so:
foo($my_array);
Output:
My name is Prince, and I am Funky
Demo
It's better to avoid extract() altogether, though. See: What is so wrong with extract()?
You can pass your array in your function as you do with any other variable
$my_array = array("a" => "Prince", "b" => "Funky"); // around 10 more
foo($my_array);
function foo($arrayData)
{
echo 'My name is '.$arrayData['a'].', and I am '.$arrayData['b'];
}
$arr[0]=123;
$a="arr[0]";
echo $$a;
gives me error
Notice: Undefined variable: arr[0]
on the last line.
What should I do to make it work?
EDIT:
Above is the simplification of what I want to do. If someone wants to know why I want to do this, then here's the explanation:
This is something like what I want to do:
if(condition){
$a=$arr1[0][0];
$b=$arr1[0][1];
$c=$arr1[0][2];
}
else{
$a=$arr2[0];
$b=$arr2[1];
$c=$arr2[2];
}
I can compact it like this:
if(condition)
$arr=$arr1[0];
else
$arr=$arr2;
$a=$arr[0];
$a=$arr[1];
$a=$arr[2];
But I wanted to try doing this using variable variable:
if(condition)
$arr="$arr1[0]";
else
$arr="$arr2";
$a={$$arr}[0];
$b={$$arr}[1];
$c={$$arr}[2];
Sure, we don't need variable variables as we can still code without them. I want to know, for learning PHP, why the code won't work.
Now that you said what you’re actually trying to accomplish: Your code doesn’t work because if you look at $arr1[0][0], only arr is the variable name; the [0] are special accessors for certain types like strings or arrays.
With variable variables you can only specify the name but not any accessor or other operation:
A variable variable takes the value of a variable and treats that as the name of a variable.
Your solution with the additional variable holding the array to access later on would be the best solution to your problem.
What you are trying to do just won't work - the code $arr[0] is referencing a variable called $arr, and then applying the array-access operator ([$key]) to get the element with key 0. There is no variable called $arr[0], so you cannot reference it with variable-variables any more than you could the expression $foo + 1 .
The real question is why you want to do this; variable variables are generally a sign of very messy code, and probably some poor choices of data structure. For instance, if you need to select one of a set of variables based on some input, you probably want a hash, and to look up an item using $hash[$item] or similar. If you need something more complex, a switch statement can often cover the cases you actually need.
If for some reason you really need to allow an arbitrary expression like $arr[0] as input and evaluate it at runtime, you could use eval(), but be very very careful of where the input is coming from, as this can be a very easy way of introducing security holes into your code.
FROM PHP DOC
In order to use variable variables with arrays, you have to resolve an ambiguity problem. That is, if you write $$a[1] then the parser needs to know if you meant to use $a[1] as a variable, or if you wanted $$a as the variable and then the [1] index from that variable. The syntax for resolving this ambiguity is: ${$a[1]} for the first case and ${$a}[1] for the second.
Use
echo ${$a}[0]; // 123
Edit : Based on your edit you can simply have
list($a, $b, $c) = (condition) ? $arr1[0] : $arr2;
Or
$array = (condition) ? $arr1[0] : $arr2;
$a = $array[0];
$b = $array[1];
$c = $array[2];
As pointed out you don't need variable variables. To get a PHP variable variable name containing index (a key) use array_keys() or array_search() or other array parsers. From php's site:
$array = array(0 => 'blue', 1 => 'red', 2 => 'green', 3 => 'red');
$key = array_search('green', $array); // $key = 2;
$key = array_search('red', $array); // $key = 1;
You could also use the following (using $var= instead of echo):
$arr[0]=123;
$arr[1]=456;
foreach ($arr as $key => $value) {
echo "arr[{$key}] = {$value} \r\n";
}
Which outputs:
arr[0] = 123
arr[1] = 456
But I don't see why you'd do that, since the whole point of the array is not doing that kind of stuff.