ポンコツエンジニアのごじゃっぺ開発日記。

いろいろポンコツだけど、気にするな。プログラム&ロボット大好きなポンコツが日々の記録を残していきます。 自動で収入を得られるサービスやシステムを作ることが目標!!

PHP5系からPHP7系に移行時の可変変数の配列の評価順には気をつけろ。

PHP7にバージョンが上がってから結構経ち、すでにPHP7.2まで上がっています。PHP7系になると変わることがたくさんで、ドキュメントを見ればわかるのですが、すべてを把握するのが大変。なので、毎回、実際に問題にぶつかってから調べちゃいます。

実際にプログラムを書いて動かしてみる

さて、今回ぶつかった問題は、「可変変数」の可変プロパティが配列の場合の問題です。

以下のようなプログラムを用意しました。

[code lang="php" title="test.php"] <?php

$a['a'] = 'b'; $b['a'] = 'c'; $c = 'b';

var_dump($$a['a']); var_dump($$c['a']); [/code]

わかりにくいかもしれないですが、可変変数と配列を組み合わせたものを出力するだけのプログラムです。

これを以下のように実行します。

[code lang="bash"]

$ php test.php

[/code]

 

この時、PHPのバージョンの違いによる結果の違いを見ていきたいと思います。

まずはPHP5系の場合です。PHPのバージョンは5.6.35を使っています。

[code lang="bash" title="PHP5.xの場合"]

$ 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 </pre></pre>

$ php test.php array(1) { ["a"]=> string(1) "c" } PHP Warning: Illegal string offset 'a' in /home/iwakami_yuki/test.php on line 8

Warning: Illegal string offset 'a' in /home/iwakami_yuki/test.php on line 8 array(1) { ["a"]=> string(1) "c" } [/code]

次にPHP7系の場合です。

[code lang="bash" title="PHP7.xの場合"]

$ 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"

[/code]

エラーが出てわかりにくいですが、このように実行結果が異なります。

ドキュメントを見てみる

さて、実際にドキュメントを見てみましょう。

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

わかりやすい表ですね。

 

まとめ

可変変数の可変プロパティが配列の場合は波括弧を使いましょうということですね。

[code lang="php"]

<?php

$a['a'] = 'b'; $b['a'] = 'c'; $c = 'b';

var_dump(${$a['a']}); var_dump(($$c)['a']);

[/code]

このように書けば、PHP7環境でもPHP5環境と同じ結果になるようになります。