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.
Related
I'm new to PHP and I got somebody else's code to work on.
There are multiple variables including $CARD.
But unlike other variables $CARD cannot display a character.
For example, when I input a value like 'passw0rd', all the other variables outputs 'passw0rd'. But the $CARD variable outputs a '0'.
And also, when I take an input like '0123', all the other variables outputs the same '0123'. But only the $CARD variable drops the 0 and outputs '123'.
Is there any PHP elements that I should be suspecting/?
If you see some thing like this in the code. that $CARD variable is cast to int.
$num = "3.14";
$CARD = (int)$num;
You can convert it to string as follows.
$var2 = (string)$CARD;
I'm reading som legacy code and come over a curious case:
$my_assoc_array; /* User defined associative array */
$my_key; /* User defined String */
$value = $my_assoc_array["$my_key"];
Is there any clever reason why you would want to have citation marks (") around the variable when it's used as a key? Like a very special corner case? Or is there simply no reason at all to do this?
-- EDIT --
Maybe in some old version of PHP there was a difference? (Remember this is legacy code).
There is one example that I can find where the output differs which is when $mykey = false.
(which perhaps does not apply to your example where $mykey is a string, but then again: this is the wild wild world of PHP)
<?php
$arr = array("1"=>"b", "0"=>"a");
$mykey = false;
var_dump($arr[$mykey]);
// returns "a"
var_dump($arr["$mykey"]);
// gives Undefined index error
$mykey = true;
var_dump($arr[$mykey]);
// returns "b"
var_dump($arr["$mykey"]);
// returns "b"
What this can be (mis-)used for beats me...
Its not necessary to bind variable name with double quotes inside array index:
you can simply write with out quotes:
$value = $my_assoc_array[$my_key];
it will be different one if $my_key is an integer value
$my_key = 3; /* User defined String */
$value = $my_assoc_array["$my_key"]; /* returns $my_assoc_array["3"] */
$value = $my_assoc_array[$my_key]; /* returns $my_assoc_array[3] */
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 tried to find a proper and explanatory title but I couldn't and I will try to explain what I am asking here:
Normally if you don't assign an empty array to a variable, you can start assign values to indexes like this:
$hello["world"] = "Hello World";
...
echo $hello["world"];
but I always encounter such definition:
$hello = array() //assigning an empty array first
$hello["hello"] = "World";
...
echo $hello["hello"];
Why is it used a lot. Is there a performance gain or something with the second one?
Thanks.
Two reasons:
Better readability (you know the array is initialized at this point)
Security - when running on a system with register_globals enabled a user could add e.g. hello[moo]=something to the query string and the array would already be initialized with this. $hello = array(); overwrites this value though since a new array is created.
Initializing your variables is good practice.
Take for example this:
$foo = 'bar';
// 10 lines and 1 year later
$foo['baz'] = 'test';
Congratulations, you now have the string "tar".
This may happen accidentally and introduce needless bugs. It gets even worse with conditional variable creation. It's avoided easily by getting into the good habit of explicitly initializing your variables.
$hello = array();
if(someConditionIsTrue){
$hello["world"] = "Hello World";
}
foreach($hello as $val){ // this will not give you any error or warning.
echo $val;
}
But
if(someConditionIsTrue){
$hello["world"] = "Hello World";
}
foreach($hello as $val){ // this will give you error .
echo $val;
}
If I remember correctly, the first one will produce a warning by PHP if you have error_reporting as E_ALL. You should always use the second method because it explicitly initialises a new array. If you are looking through code and out of nowhere see $hello["hello"] but cannot recall seeing any reference to $hello before, it would be confusing.
The same will happen if you do $hello[] = "World", a warning will be displayed