PHP の array_reverse() の使用上の注意
PHP の関数 array_reverse()
を使っていて挙動に驚いたので備忘録を残しておきます。
array_reverse()
は配列の要素の順番を逆にした配列を生成して返してくれる関数です。
通常の使用例は次のとおりです。
インデックス配列:
$original = [5, 9, 6, 3];
array_reverse($original);
// => [3, 6, 9, 5]
連想配列:
$original = ['orange' => 2, 'apple' => 5];
array_reverse($original);
// => ['apple' => 5, 'orange' => 2]
いずれも直感的で自然なふるまいですね。
注意すべきなのは要素数が 1 の連想配列の場合です。例えば次の場合。
$original = [1000 => 'car'];
array_reverse($original);
// => ['car']
array_reverse()
の戻り値からは、元々の配列のキー 1000
がなくなっています。
要素数 1 の配列を裏返してもメリットがないので、その意味ではこれは利用側の問題で「利用する側で注意すべき問題かな」とも思えますが、厄介なのは一見インデックス配列ではない配列の場合です。
キーが数字に変換できる文字列の場合:
array_reverse(['1998' => 'car']);
// => ["car"]
この場合はおそらく多くの利用者にとって想定外のふるまいになります。
ちょっと調べたところこのふるまいは仕様とのことで・・・ array_reverse()
の第 2 引数に TRUE
を渡せばこの問題は回避できるようになっています。
PHP の公式ドキュメントで関数の宣言部を確認すると次のようになっています。
array array_reverse ( array $array [, bool $preserve_keys = false ] )
第 2 引数についての説明はこちら。
preserve_keys: If set to TRUE numeric keys are preserved. Non-numeric keys are not affected by this setting and will always be preserved.
つまり、第 2 引数に TRUE
を渡すとキーがキーが保持されるようになります。
array_reverse(['1998' => 'car'], TRUE);
// => [1998 => 'car']
ただし、キーが FALSE
である要素の場合は第 2 引数の有無にかかわらずキーが消失します。
これが仕様なのかどうなのかはよくわかりませんが、思わぬバグの原因にはなりそうです。
キーが FALSE
の場合:
array_reverse([FALSE => 'car']);
// => ["car"]
ちなみに、キーが NULL
や空文字列の場合は、 FALSE
とはまた違った挙動となります。
array_reverse([NULL => 'car']);
// => ["" => "car"]
array_reverse(['' => 'car']);
// => ["" => "car"]
何じゃこれは。 PHP はこういうもの、利用者側の問題だよと言われればそれまでですが、注意が必要ですね。