views:

128

answers:

5

Variable variables seem pretty cool, but I can't think of a scenario where one would actually use them in a production environment. Have you done so? How did you use them?

+4  A: 

Its purpose, I guess, is to allow novice programmers to dynamically change data without using "complicated stuff" like composite types (arrays and objects).

Seems like something something Rasmus would consider a good idea.

I never use them.

Artefacto
A: 

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 pass variables into it for use.

echo fetch_template('hi_there.tpl', array('name'=>'JJ'));

Then in your template:

Hello <?php echo $name; ?>!
Jage
This same thing can be done with [`extract`](http://ca.php.net/manual/en/function.extract.php)
Daniel Vandersluis
And 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
@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
@Jage sorry, missed the comment
Daniel Vandersluis
A: 

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)...

ircmaxell
Those are not variable variables. Methods are not variables.
Artefacto
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
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
A: 

I found useful in single scenario . I was having youtube API results in json format like this

 $obj->media$title => Video title

So i used like

$mt = 'media$title';
$obj->$mt ;

So worked for me here :)

Arsheep
You could just do `$obj->{'media$title'}`.
Artefacto
A: 

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.

konforce