いろいろな言語で配列の最後の要素でPHPがハブられてました。
ということでここでやりましょう。
最後の要素をとる関数 end に副作用があるらしい。
see PHP – 配列の最後の要素の判定にend()は使わない方がいい話
see PHPで配列の最後の値を取得する
end を使うべきかどうかはケースバイケース。PHP 難しい。
配列にendを使って問題になるのはよほど特殊なケースだけなので、通常はendを使ってしまって問題ありません。
$array = [1, 2, 3];
$value = end($array); // 3
副作用としては$array
の配列ポインタが配列の最後になるので、その後リセットせずにcurrentやnextあたりを使うと想定外の値が返ってくる場合があります。
しかしresetとend以外の配列ポインタ操作関数を使うのは変態だけなので、一般人には影響しません。
あらゆる配列操作はforeachを使うべきで、そしてforeachは配列ポインタとは関係なく全件ループする1ので、配列ポインタの現在地などは意識しなくていいです。
実用的な問題としては、endは参照なので値しか渡せません。
つまりend(getArray());
のようなことができません。
ということでPHP7.3.0でarray_key_lastが実装されました。
// 配列ポインタを変えずに最後の値を取得
$array = [1, 2, 3];
$value = $array[array_key_last($array)]; // 3
// 関数も渡せる
function getArray(){ return [1, 2, 3]; }
$value = getArray()[array_key_last(getArray())]; // 3
なぜかarray_value_lastは却下されてしまったので、$value = array_value_last($array)
とは書けません。残念ですね。
ちなみに、冒頭の記事で紹介されている配列の最後の要素の判定にend()は使わない方がいい話は単に使い方が間違ってるだけですね。
値を比較してるから同じ値がイコールになっているだけで、end云々は全く関係ありません。
正しい判定にはキーを使います。
$array = [
0 => "aaa",
1 => "bbb",
2 => "ccc",
3 => "bbb",
4 => "ddd",
5 => "ccc"];
// 7.3.0以降は$key = array_key_last($array);
end($array);
$key = key($array);
foreach($array as $k=>$v){
if($k !== $key){
print "${k}=>${v} まだ最後じゃないよ\n";
}else{
print "${k}=>${v} これが最後だよ\n";
}
}
7.3.0未満は$key
の求め方が残念な感じ。
-
正確には『PHP7では全く無関係』『PHP5では配列ポインタをリセットする』。いずれにせよ配列ポインタの現在地にかかわらず全件ループする。 ↩