PHP 陣列取最後元素三大寫法:end()、array_key_last()、array_slice() 實測與最佳選擇
需取得陣列最後一筆資料?本文比較三種常見寫法的行為差異、效能特徵與適用場景,避免常見陷阱。
寫法比較
| 寫法 | 程式碼 | 回傳值 | 副作用 | PHP 版本 |
end() | end($arr) | 最後元素**值** | **移動內部指標**至最後 | 所有 |
array_key_last() | $arr[array_key_last($arr)] | 最後元素**值** | 無副作用 (PHP 7.3+) | 7.3+ |
array_slice() | array_slice($arr, -1, 1) | 包含最後元素的**陣列** | 無副作用、複製陣列 | 所有 |
array_pop() | array_pop($arr) | 最後元素**值** | **刪除**最後元素 | 所有 |
效能微測試 (100 萬次)
<?php
$arr = range(1, 100);
$iterations = 1_000_000;
$start = hrtime(true);
for ($i = 0; $i < $iterations; $i++) end($arr);
echo "end(): " . (hrtime(true) - $start) / 1e6 . " ms\n";
$start = hrtime(true);
for ($i = 0; $i < $iterations; $i++) $v = $arr[array_key_last($arr)];
echo "array_key_last(): " . (hrtime(true) - $start) / 1e6 . " ms\n";
$start = hrtime(true);
for ($i = 0; $i < $iterations; $i++) $v = array_slice($arr, -1, 1)[0];
echo "array_slice(): " . (hrtime(true) - $start) / 1e6 . " ms\n";
// 典型結果 (PHP 8.2):
// end(): ~45 ms
// array_key_last(): ~38 ms
// array_slice(): ~120 ms (因陣列複製)
?>
行為差異實測
<?php
$arr = ['a' => 1, 'b' => 2, 'c' => 3];
// 1. end() 會移動指標
echo end($arr); // 3
echo current($arr); // 3 (指標已在最後)
next($arr); // false
reset($arr); // 需手動 reset
// 2. array_key_last() 不影響指標
$key = array_key_last($arr); // 'c'
echo $arr[$key]; // 3
echo current($arr); // 1 (指標仍在開頭)
// 3. array_slice() 回傳陣列
$last = array_slice($arr, -1, 1); // ['c' => 3]
echo $last['c']; // 3
// 原陣列不變
// 4. 關鍵字鍵名非連續數字
$arr2 = [10 => 'x', 20 => 'y', 5 => 'z'];
echo end($arr2); // 'z' (正確)
echo $arr2[array_key_last($arr2)]; // 'z' (正確)
echo array_slice($arr2, -1, 1)[5]; // 'z' (需知道鍵名)
// 注意:array_slice(-1) 保留鍵名,但若用 [0] 取值會失敗
最佳實務建議
- PHP 7.3+ 專案:優先用
$arr[array_key_last($arr)] — 無副作用、語意清晰、效能最佳。
- 需同時取得鍵名與值:
[$key => $val] = array_slice($arr, -1, 1, true); (保留鍵名)。
- 舊版本 PHP / 簡單腳本:
end($arr) 可接受,但記得後續 reset($arr)。
- 絕對避免
array_pop() 除非你**真的要刪除**最後元素。
- 物件/Iterator:用
iterator_to_array($it)[$key] 或 new ArrayIterator($it) 配合 seek()。
常見陷阱
| 陷阱 | 錯誤結果 | 原因 |
array_slice($arr, -1)[0] | 鍵名非 0 時取錯值 | 保留原鍵名,索引 0 不存在 |
end($arr) 後 foreach | foreach 從頭開始 (PHP 重置指標) | foreach 不受內部指標影響 |
| 空陣列 | end([]) 回傳 false、array_key_last([]) 回傳 null | 需先 if ($arr) 判斷 |