schedule2020-01-15

PHP compact関数で宣言していない変数の扱い

PHPのバージョンアップ対応をしていた際に、compactで宣言していない変数の扱いが変わっていたので書き留めておく。

compact関数とは

compact - PHP.net

変数名とその値から配列を作成する関数。 変数名の文字列を引数に渡す。

$a = 'hoge';
$b = 123;
var_dump(compact('a','b'));

これを実行すると、以下のようになる。

array(2) {
  ["a"]=>
  string(4) "hoge"
  ["b"]=>
  int(123)
}

個人的に、この関数はLaravelのViewに渡す変数の配列を作るときに重宝している。

変更点

PHP7.3からcompact関数が未定義の渡された変数をエラーとするよう変更となった。 PHP RFC: Make compact function reports undefined passed variables

先ほどのコードに未定義の変数$c`を渡して実行する。

<?php
$a = 'hoge';
$b = 123;
var_dump(compact('a','b','c'));

PHP 4.3.0 から 7.2.26 まで

array(2) {
  ["a"]=>
  string(4) "hoge"
  ["b"]=>
  int(123)
}

未定義の変数$c`は無視されて、エラー無く実行できる。

PHP 7.3.0 以降

Notice: compact(): Undefined variable: c in /in/00LYO on line 4
array(2) {
  ["a"]=>
  string(4) "hoge"
  ["b"]=>
  int(123)
}

未定義の変数: cと警告(E_NOTICE)が出る。

if分岐に依って未定義変数を渡してしまうことに注意しよう。

例として、LarabelのViewに渡すとき。

$result = SomeEloquent::find($id); // なにかの検索結果
if(empty($result)){
    $error_msg = "Not Found";
}
view($view, compact('result', 'error_msg'));
// => compact(): Undefined variable: error_msg 

以上は、異なるバージョンのPHPをシミュレーションできる3v4l.orgで実行した。 (どのバージョンから変更があったかすぐわかるので便利)