It comes down to order of operations and how PHP type juggles. Hint: var_dump
is your friend, echo
always casts to a string so it is the worst operation for analyzing variable values, esp in debug settings.
Consider the following:
var_dump($a->$c); // array (size=1) / 'start' => int 2
var_dump($a->$c['start']); // array (size=1) / 'start' => int 2
var_dump($a->b['start']); // int 2
var_dump($c['start']); // string 'b' (length=1)
The key here is how PHP interprets the part of $c['start']
(include $c[0]
here as well). $c
is the string 'b'
, and when attempting to get the 'start'
index of string 'b
' this simply returns the first character in the string, which happens to simply be the only letter (b) in the string. You can test this out by using $c = 'bcdefg';
- it'll yield the same result (in this specific case). Also, $c['bogus']
will yield the exact same thing as $c['start']
; food for thought, and make sure you do the required reading I linked to.
So with this in mind (knowing that $c['start']
reluctantly returns 'b'
), the expression $a->$c['start']
is interpreted at $a->b
. That is, the order is $a->($c['start'])
and not ($a->$c)['start']
.
Unfortunately you can't use ()
nor {}
to steer the parser (PHP SCREAM
s), so you won't be able to accomplish what you want in a single line. The following will work:
$e = 'start';
$interim = $a->$c;
echo $interim[$e];
Alternatively, you can cast your arrays as objects (if you have the luxury):
$a->$c = (object) $a->$c; // mutate
var_dump($a->$c->$e);
$interim = (object) $a->$c; // clone
var_dump($interim->$e);
...by the way, referring back up to $c['start']
and $c[0]
, in regards to $c[0][0]
you simply can't do this because $c[0]
is the character b
in string 'b'
; when access the character/byte b
it will not have a property of [0]
.