Panda Blog

On 5 Nov., 2015

We write many blogs on many tech subjects. Feel free to read more here: http://www.panda-os.com/blog

Panda Blog

Feel free to read more here: http://www.panda-os.com/blog/

 

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

1
2
3
4
5
$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:

01
02
03
04
05
06
07
08
09
10
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:

01
02
03
04
05
06
07
08
09
10
11
    ...
 
    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

1
2
3
4
5
6
7
8
9
...
 
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

01
02
03
04
05
06
07
08
09
10
...
 
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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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!

Read more...