Variable variables seem pretty cool, but I can't think of a scenario where one would actually use them in a production environment. What would such a scenario be? How were they used?
6 Answers
Its purpose, I guess, is to allow novice programmers to dynamically change data without using "complicated stuff" like composite types (arrays and objects).
I never use them.
![](../../users/profiles/127724.webp)
- 90,634
- 15
- 187
- 215
-
// allow novice programmers to dynamically change data without using "complicated stuff" like composite types (arrays and objects) // It is not complicated once it has been learned. – dreftymac Nov 26 '12 at 23:18
-
1I think that's the meaning of the quotes. – user151841 Nov 27 '12 at 15:19
-
1They're totally useless. – frosty Oct 14 '15 at 18:49
A variable variable is essentially an array (map/dictionary). The following are equivalent ideas:
<?php
$foo = array('a' => 1);
$bar = 'a';
echo $foo[$bar]."\n";
$foo_a = 1;
$bar = 'a';
$vv = "foo_$bar";
echo $$vv."\n";
?>
Thus if you wrap your "variable variables" into a parent array, you can do away with them.
I've seen people use variable properties inside classes:
<?php
class Foo
{
private $a = 1;
public function __get($key)
{
if (isset($this->$key)) return $this->$key;
}
}
$foo = new Foo();
echo $foo->a;
?>
But again, you could use an array:
<?php
class Foo
{
private $props = array('a' => 1);
public function __get($key)
{
if (array_key_exists($key, $this->props))
return $this->props[$key];
}
}
$foo = new Foo();
echo $foo->a;
?>
And outside classes:
<?php
class Foo
{
public $a = 1;
}
$foo = new Foo();
$prop = 'a';
echo $foo->{$prop};
?>
So you never "have" to use variable variables or variable properties when writing your own controlled code. My personal preference is to never use variable variables. I occasionally use variable properties, but prefer to use arrays when I'll be accessing data in that way.
![](../../users/profiles/259778.webp)
- 45,217
- 11
- 82
- 95
Think of it for use in a template system where you are using PHP files and need to set in variables:
function fetch_template($file, $vars){
$ret = 'File not loaded.';
if(file_exists(TEMPLATE_PATH.$file)){
//could do this with extract() but I am showing you
foreach($vars as $varName => $value){
${$varName} = $value;
}
ob_start();
include(TEMPLATE_PATH.$file);
$ret = ob_get_contents();
ob_end_clean();
}
return $ret;
}
Now assuming you used these variable names in your template, you could call it and pass variables into it for use.
echo fetch_template('hi_there.tpl', array('name'=>'JJ'));
Then in your template:
Hello <?php echo $name; ?>!
![](../../users/profiles/63550.webp)
- 28,342
- 21
- 95
- 123
![](../../users/profiles/88310.webp)
- 7,714
- 3
- 29
- 30
-
This same thing can be done with [`extract`](http://ca.php.net/manual/en/function.extract.php) – Daniel Vandersluis Aug 19 '10 at 16:20
-
2And now you have a bug `$vars` has a key `"file"`. This is why variable variables (and `extract`, for that matter) are dangerous. Would it be so much harder to use something like `$m['var']` in the template? – Artefacto Aug 19 '10 at 16:23
-
@Daniel: the code example explicitly says that can be done with extract(). This was an example. @Artefecto: this was not produced to demonstrate security, but instead the use of variable variables. I never advocated passing in variables blindly like anything in the $_GET array. – Jage Aug 19 '10 at 16:31
Personally, I use them fairly often. All calls of the following types use variable-variables:
$foo->$bar = 'test';
$foo->$bar();
$bar();
So any time you do a dynamic method/function call, you're using variable-variables...
A common use for this is accessing protected properties via the __get
magic method. I've seen the following quite often:
public function __get($name) {
return isset($this->$name) ? $this->$name : null;
}
Which by definition is using variable variables to provide read-access to the protected members...
I've never directly used the $$var
syntax (and don't think I ever will). I have seen it used to access global variables by name global $$name; echo $$name;
, but the same thing can be done with the $_GLOBALS[$name]
syntax, so that's not a good use-case (not to mention that using global variables is usually seen as bad practice)...
![](../../users/profiles/338665.webp)
- 155,647
- 33
- 256
- 309
-
1
-
Though they can be (kind of) if this go ahead: http://wiki.php.net/rfc/closures/object-extension#status_as_of_august_10_2010 – Artefacto Aug 19 '10 at 16:33
-
It's a variable-function. You're right. It still operates on the same principal though (where the variable is dereferenced to determine the execution path)... – ircmaxell Aug 19 '10 at 16:35
I found it useful in a single scenario. I was having YouTube API results in JSON format, like this
$obj->media$title => Video title
So I used it like
$mt = 'media$title';
$obj->$mt ;
So it worked for me here :)
![](../../users/profiles/63550.webp)
- 28,342
- 21
- 95
- 123
![](../../users/profiles/349297.webp)
- 4,081
- 7
- 29
- 43
I mainly use it to reduce copy-paste in sanitizing get/post data in the begining of a php file: It makes sanitized variables with the proper names:
$fields=array('age','name','gender','email','username');
foreach($fields as $field) {
if (empty($_REQUEST[$field] === false)
${$field} = sanitize($_REQUEST[$field]);
else
${$field} = '';
}
instead of all these lines:
if (empty($_GET['age']) === false)
$age= sanitize($_GET['age']);
else
$age= '';
if (empty($_GET['name']) === false)
$name= sanitize($_GET['name']);
else
$name = '';
if (empty($_GET['gender']) === false)
$gender= sanitize($_GET['gender']);
else
$gender= '';
if (empty($_GET['email']) === false)
$email= sanitize($_GET['email']);
else
$email= '';
if (empty($_GET['username']) === false)
$username= sanitize($_GET['username']);
else
$username= '';
I hope it helps
![](../../users/profiles/879163.webp)
- 479
- 1
- 6
- 14