Search code examples
phpmigrationincompatibilityvariable-variablesphp-7

Variable variables handling order: changes in PHP 7


With the new PHP 7.0.0 out now, I'm a bit worried about the changes in evaluation order of the so-called 'variable variables'.

On this page, under 'Changes to variable handling', a table is displayed with examples of expressions with their handling order in PHP 5 and PHP 7. The four expressions listed are:

$$foo['bar']['baz']
$foo->$bar['baz']
$foo->$bar['baz']()
Foo::$bar['baz']()

Given the following string and array:

$qux = 'quux';
$foo = array('bar' => array('baz' => 'qux'));

the first expression in the table $$foo['bar']['baz'] is interpreted in PHP 5 as the value of a variable named as the value in $foo['bar']['baz'], thus the value of $qux, which is 'quux'.

However, in PHP 7, as I understand it, the same expression will be interpreted as a variable named as the value in $foo, thus I expect a PHP Notice for an 'array to string conversion', since $foo is an array.

The other examples in the table seem to be a variation of this same theme.

Of course I'm curious to why this is changed in PHP 7 (specifically, why is this change more important than being backwards compatible), however, that's not a suitable question for SO. My question is more practical:

What would be the recommended way of coping with this incompatibility?

Of course, adding curly braces to the offending expressions will help (${$foo['bar']['baz']}, $foo->{$bar['baz']}, $foo->{$bar['baz']}() and Foo::{$bar['baz']}()), but this is very cumbersome, going through tons of old code, searching for relatively few occurances...

Otherwise, are these four examples the only possible syntax variations? That is, can I create a RegExp and grep all offending code? What other variations might exist?


Solution

  • Rasmus Lerdorf wrote a static analysis tool that can spot these so-called Uniform Variable Syntax issues, called Phan https://github.com/etsy/phan

    Phan has the option -b, --backward-compatibility-checks to check for potential PHP 5 -> PHP 7 BC issues.