PHP7にバージョンが上がってから結構経ち、すでにPHP7.2まで上がっています。PHP7系になると変わることがたくさんで、ドキュメントを見ればわかるのですが、すべてを把握するのが大変。なので、毎回、実際に問題にぶつかってから調べちゃいます。
実際にプログラムを書いて動かしてみる
さて、今回ぶつかった問題は、「可変変数」の可変プロパティが配列の場合の問題です。
以下のようなプログラムを用意しました。
<?php $a['a'] = 'b'; $b['a'] = 'c'; $c = 'b'; var_dump($$a['a']); var_dump($$c['a']);
わかりにくいかもしれないですが、可変変数と配列を組み合わせたものを出力するだけのプログラムです。
これを以下のように実行します。
$ php test.php
この時、PHPのバージョンの違いによる結果の違いを見ていきたいと思います。
まずはPHP5系の場合です。PHPのバージョンは5.6.35を使っています。
$ php -v PHP 5.6.35 (cli) (built: Mar 30 2018 09:32:52) Copyright (c) 1997-2016 The PHP Group Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies &amp;lt;/pre&amp;gt;&lt;/pre&gt; $ php test.php array(1) { ["a"]=&gt; string(1) "c" } PHP Warning: Illegal string offset 'a' in /home/ponkotsu/test.php on line 8 Warning: Illegal string offset 'a' in /home/ponkotsu/test.php on line 8 array(1) { ["a"]=&gt; string(1) "c" }
次にPHP7系の場合です。
$ php -v PHP 7.2.3 (cli) (built: Mar 1 2018 14:56:34) ( NTS ) Copyright (c) 1997-2018 The PHP Group Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies with Zend OPcache v7.2.3, Copyright (c) 1999-2018, by Zend Technologies $ php test.php PHP Notice: Array to string conversion in /home/user/test.php on line 7 Notice: Array to string conversion in /home/user/test.php on line 7 PHP Notice: Undefined variable: Array in /home/user/test.php on line 7 Notice: Undefined variable: Array in /home/user/test.php on line 7 NULL string(1) "c"
エラーが出てわかりにくいですが、このように実行結果が異なります。
ドキュメントを見てみる
さて、実際にドキュメントを見てみましょう。
PHPマニュアル > 言語リファレンス > 変数の可変変数のページ(http://php.net/manual/ja/language.variables.variable.php)にはこんな注意書きが書いてあります。
警告 可変プロパティが配列である場合の解決方法が、PHP 5 と PHP 7 では異なります。 PHP 7.0 移行ガイド に、変更点の詳細をまとめました。また、波括弧を使って曖昧さを除去する方法も示します。
なるほど、そうですね。波括弧を使うことで曖昧さを除去しましょうということですね。
PHP7.0移行ガイドのページにしっかりまとまっていました。(http://php.net/manual/ja/migration70.incompatible.php#migration70.incompatible.variable-handling.indirect)
わかりやすい表ですね。
まとめ
可変変数の可変プロパティが配列の場合は波括弧を使いましょうということですね。
<?php $a['a'] = 'b'; $b['a'] = 'c'; $c = 'b'; var_dump(${$a['a']}); var_dump(($$c)['a']);
このように書けば、PHP7環境でもPHP5環境と同じ結果になるようになります。