1

Consider this :

$a = 'u';
$b[$a] = 'v';
$c[$b[$a]] = 'w';

This works fine:

php > echo $c[$b[$a]];
w

This also works:

php > echo '$c[$b[$a]]';
'$c[$b[$a]]'

However this leads to a syntax error:

php > echo "$c[$b[$a]]";

PHP Parse error: syntax error, unexpected '[', expecting ']'

While a shorter version works:

php > echo "$b[$a]";
v

Why?

halfer
  • 19,824
  • 17
  • 99
  • 186
Skippy le Grand Gourou
  • 6,976
  • 4
  • 60
  • 76
  • Just check: https://3v4l.org/rJbsY What is your php versions on the test machine and on the your server? – sectus May 17 '16 at 10:11
  • I can't reproduce this. It works both in CLI and on Apache2. Its more likely to do with code surrounding the assignment rather than the assignment itself. – apokryfos May 17 '16 at 10:16
  • @sectus : Just narrowed down the issue, this is not a server issue but a syntax issue. I'm still interested in the explanation, I'll rephrase the question entirely, please check again in 2 minutes. – Skippy le Grand Gourou May 17 '16 at 10:18
  • Related, though it doesn't answer this question : http://stackoverflow.com/q/3446216/812102 – Skippy le Grand Gourou May 17 '16 at 10:35
  • You can add braces in in-string array expressions, like `echo "{$b[$a]}";` - maybe that will help resolve the more complex variant? – halfer May 17 '16 at 10:41
  • @halfer : I tried several variations (e.g. https://3v4l.org/8aPGo), without success. BTW I'm not trying to solve an issue (anymore), I'd just like to understand the behaviour. – Skippy le Grand Gourou May 17 '16 at 11:44

2 Answers2

3

The short answer is: don't write PHP like this! If it is confusing to read then use an intermediate variable.

However, it can be fixed: it looks like PHP just wants the brace delimiters at the outermost edges of the variable:

<?php
$a = 'u';
$b[$a] = 'v';
$c[$b[$a]] = 'w';

echo "{$c[$b[$a]]}";

This is also fine as well:

echo "${c[$b[$a]]}";

In the first case, the whole thing is wrapped in braces, and in the second, the $ is allowed outside of the brace construct to say that the next bit is a variable.

halfer
  • 19,824
  • 17
  • 99
  • 186
3

In a double quoted string there are two kinds of variable parsing, simple and complex. Simple parsing will only work with a single dimensional array or object. So these will work:

echo "Valid: $foo[1]";
echo "Valid: $foo[bar]";
echo "Valid: $foo->bar";

But these will not:

echo "Invalid: $foo[1][2]";
echo "Invalid: $foo->bar->baz";
echo "Invalid: $foo->bar()[2]";

Complex parsing is what halfer suggested in his answer, which wraps the expression in curly braces, and will indeed solve your problem:

echo "Valid: ${foo[1][2]}";
echo "Valid: ${foo->bar->baz}";
echo "Valid: ${foo->bar()[2]}";
miken32
  • 42,008
  • 16
  • 111
  • 154