PHPの配列は暗黙的に自動で作られる
PHPの配列の作り方。
$array = [];
$array = array();
$array = ['key' => 'value'];
このあたりは普通に使ってたんですが、PHPの配列は思ってたより暗黙的に生成されるみたいです。
15年近くPHP使ってるんですが、「そういうのwarningでなかったっけ・・・?」みたいな思い込みがいろいろあったので、整理してみました。
以下PHP8.3で試しました。
null に push できる
まず、 null
に値をpushすることができます。
$arr = null;
$arr[] = 1;
var_dump($arr);
//> array(1) { [0]=> int(1) }
null
が勝手に array
に変化して、値をpushすることができました。
すごい。
同様に、未定義状態から一気に配列が作れます。
$array[] = 1;
var_dump($array);
//> array(1) { [0]=> int(1) }
PHPマニュアルにも以下のように記載があります。
$arr がまだ存在しない場合、 あるいは null や false に設定されている場合は、 新しく配列を作成します。 つまり、これは配列を作成する方法のひとつでもあります。
ただし、マニュアルに以下の記載があるように、これはオススメの方法ではないので利用を推奨しません。
「へー!そんなことできたんだ!」といった驚きでした。
とはいえ、この方法を使うことはおすすめしません。なぜなら、既に $arr に何らかの値 (リクエスト変数からの文字列など) が入っている場合にはその値がそのまま残り、 [] が実際には 文字列アクセス演算子 を表してしまうからです。 変数を初期化するときには、直接代入するほうがよいでしょう。
false はだめよ
記載どおり同様に false
に値をpushすることもできましたが、これは非推奨になったようです。
$arr = false;
$arr[] = 1;
// DEPRECATED Automatic conversion of false to array is deprecated.
また、 string
などのその他のスカラー値(true含む)に対してはpushできずエラーになります。
null に値をセットできる
pushと同様なんですが、キーを指定しての値のセットでもできました。
$arr = null;
$arr['foo'] = 1;
var_dump($arr);
//> array(1) { ["foo"] => int(1) }
こちらも未定義状態から一気に配列を作ることができます。
$array['key'] = 'value';
var_dump($array);
//> array(1) { ["key"]=> string(5) "value" }
ネストしたキーは勝手に生成される
null
にpush/セットできる挙動の延長線上だとは思うのですが、ネストしたキーが存在しなかった場合、勝手に配列を生成してくれるようです。
どういうことかというと、
$array['foo']['bar'][] = 0;
var_dump($array);
//> array(1) {
["foo"]=>
array(1) {
["bar"]=>
array(1) {
[0]=>
int(0)
}
}
}
このように、存在しなかった $array['foo']['bar']
が暗黙的に配列として生成され、そこに 0
がpushされたり、
$array['a']['b']['c'] = 1;
var_dump($array);
//> array(1) {
["a"]=>
array(1) {
["b"]=>
array(1) {
["c"]=>
int(1)
}
}
}
このように、存在しなかった $array['a']['b']
を暗黙的に配列として生成し、 'c' => 1
をセットしてくれました。
これまでのやり方
これまで、以下みたいに is_array()
や array_key_exists()
使ってキーの存在チェック、なければ空配列を作る、そのうえで代入みたいなことをやってたんですが、これが不要なようです。
$foo = [1,2,3];
$array = [];
foreach($foo as $index => $bar) {
if (!array_key_exists($index, $array)) {
$array[$index] = [];
}
$array[$index][] = $bar * 2;
}
暗黙的な配列生成を使ったやり方
$foo = [1,2,3];
$array = [];
foreach($foo as $index => $bar) {
$array[$index][] = $bar * 2;
}
シンプルでいいですね。
この挙動について「コレ!」という仕様が書いてあるPHPマニュアルのページは見つけられなかったんですが、前述の「nullに対して勝手に値をpush/セットできる」という仕様の延長線上の話だと思うので、まぁこの挙動自体は仕様として解釈しても大丈夫かなぁと思ってます。
いつかdeprecatedになることもあまりないのでは、という期待はもてそうかなと。
何でwarningが出るのか
冒頭に書いたように、これらの配列関係で何かwarningがでた記憶がありました。
代入ではなくて参照でのwarningのようです。
// 未定義の変数のキーにアクセス
var_dump($undefinedArray['a']);
// WARNING Undefined variable $undefinedArray.
// WARNING Trying to access array offset on null.
//> null
それでも値は返してくれるあたりがPHPぽいですね。
Discussion