3

I understand the concept of variable variables in PHP. According to my understanding of variable variables in PHP the following code:

$foo = 'hello';
$$foo = 'world';

echo $foo . ' ' . $hello;

Will generate the output as:

Hello World

But I am finding it difficult to understand the case of variable object properties

Say I have a class called foo with a single property as follows:

class foo {    
    var $r   = 'I am r.';
}

Now, creating the instance of the class foo and using the concept of variable variables the following code:

$foo = new foo();

$bar = 'r';
echo $foo->$bar;

will output:

I am r.

Up till everything is fine, but when I include a property having an array value it gets messed up for me. Say for example I add another property with array value to the class foo and now the class looks like:

class foo {    
    var $arr = array('I am A.', 'I am B.', 'I am C.');
    var $r   = 'I am r.';
}

Now When I create the instance of the class foo and try to read the property $arr[1] as follows:

$arr = 'arr';
echo $foo->$arr[1];

Which outputs:

I am r.

and the output looks weird to me. I mean how does $foo->$arr[1] resolves to the propery $r in the class foo ?

Shouldn't doing $foo->$arr resolve into $foo->arr[1] (Note: There is no dollar sign) giving the output:

I am B.

How does this happen?

I am aware that doing $foor{$arr}[1] outputs "I am B."

My question is why does $foo->$arr doesn't resolve into $foo->arr ? Given that the variable $arr is holding the value 'arr' ?

A note to admins/supervisors: This question is not a duplicate; I have tried searching for the similar questions but none of it answered what I need to know.

Rahul Bhanushali
  • 553
  • 5
  • 14

1 Answers1

7
class foo {    
    var $arr = array('I am A.', 'I am B.', 'I am C.');
    var $r   = 'I am r.';
}

$foo = new foo;
$arr = 'arr';
echo $foo->$arr[1];

It's order of precedence that's biting you here. The last line could be re-written as

echo $foo->{$arr[1]};

Since strings are arrays starting with index 0, $arr[1] references the second character in 'arr', i.e. 'r', and results in printing the string 'I am r.'.

To get the results you're expecting, you need to explicitly tell PHP which part of the expression is meant as the variable name, because by default it greedily takes pretty much everything. Replacing the last line with this will get the output you expect:

echo $foo->{$arr}[1];

This will evaluate $arr to its full string 'arr', and then use that as the label to the class member $arr in foo; the index will then grab the second entry in that array, 'I am B.'.

Kromey
  • 1,202
  • 1
  • 10
  • 13
  • Very cool site there, @KarolyHorvath. Here's proof-of-concept of my full answer: http://ideone.com/VGmLP8 – Kromey Apr 03 '14 at 18:41
  • I am aware of the solution you provided using curly braces and I have already mentioned it in my question as well. And your answer saved my lots of time. Thank you very much. I tried accepting the answer but stack overflow says I cannot accept an answer in 4 mins. Thank you mate once again. – Rahul Bhanushali Apr 03 '14 at 18:41
  • Ah, you hadn't added that bit with the curly braces when I'd started writing my answer (or I overlooked it somehow). Still, it's helpful to see the full context in the answer, so I'll leave it be. – Kromey Apr 03 '14 at 18:43
  • I had from the begining. But thats not an issue. You solved my problem thank you friend. – Rahul Bhanushali Apr 03 '14 at 18:59