PHP’s Variable Variables

Today we’re talking dollars, who doesn’t love them right?!
Well, not your regular wallet dollars, further than that, not even your regular $var dollars.
We are talking about the Dollar dollar variable declaration.

$$ is one of the less known PHP features that with right use might be very useful creating a dynamic code.

What exactly is $$?

The $$ sign gives us the ability to create a variable named out of another variable’s value, lets have a look on a simple declaration

$hello = 'world';
$$hello = 'great';

echo $hello; //Echos 'world'
echo $world; //Echos 'great'

So what exactly have we done here? We have created two new variables, the first ‘$hello’ which contains ‘world’ and the second is ‘world’ which contains ‘hello’.
You’re probably thinking right now “Ok so what would you actually do with it?”

Using $$ to create a dynamic constructor

A dynamic constructor can be very helpful on a dynamic code that changes a lot, lets have a look on how to use $$ in order to create one.
Let’s assume we have a class Person with some variables in it which might look like this:

class Person
{

    private $firstName;
    private $lastName;
    private $age;
    private $gender;

    //Getters & setters for each var
}

Now lets assume we want to init these variables on construct, we’ll have to add our constructor to look like this:

    ...

    public function __construct($firstName, $lastName, $age, $gender)
    {
        $this->firstName = $firstName;
        $this->lastName = $lastName;
        //etc..
    }

    //Getters & setters for each var
}

For a small class like our person, this code actually looks pretty good, but imagine we have 20 variables in the class? Having a huge constructor with many $this->_x = x; might be a huge mess.
So lets apply some of the $$ magic to our constructor

    ...

    public function __construct($params)
    {
        foreach($params as $key => $value) {
            $this->{$key} = $value;
            //Which is equal to ${$key} or $$key only using $this keyword to address the class var
        }
    }

With this new constructor we can send an associated array with only the params we want to init and their values.
Allowing us to change the class and add or remove vars without changing the class declaration.

A word on security

The constructor we just used to init our class is great but what will happen if we’ll send a variable that does not exists as a var in our class? Well, you’ve guessed correct, we have a new unwanted var in our class!
In order to prevent that kind of mess, we can check for existing vars.
Lets enhance our constructor

    ...

    public function __construct($params)
    {
         foreach($params as $key => $value) {
              if(array_key_exists($key, (get_object_vars($this)) {
                  $this->{$key} = $value;
              }
          }
     }

This way we only init variables that actually exist in our class and not every variable sent to the constructor.
Lets have a look on the full code

class Person
{
    private $firstName;
    private $lastName;
    private $age;
    private $gender;

    public function __construct($params)
    {
         foreach($params as $key => $value) {
              if(array_key_exists($key, (get_object_vars($this)) {
                  $this->{$key} = $value;
              }
          }
     }

     //Getters & Setters
}

//Creating a new object of person
$personParams = [
    'firstName' => 'Panda',
    'age' => 3,
    'not-a-var' => 'this wont work!'
];

$person = new Person($personParams);

As we can see, the dollar dollar variable can be a useful feature in order to keep our code fully dynamic and subtle to changes without big refactoring of our code.
We just have to make sure we’re not opening our code to changes and unwanted variables!

Leave a Reply

Your email address will not be published. Required fields are marked *