PHP 刪除陣列元素有兩種主流做法:unset() 與 array_splice()。兩者在索引重組、效能、回傳值上有本質差異,選錯會導致邏輯錯誤。本文深度比較並給出最佳實踐。
| 特性 | unset() | array_splice() |
|---|---|---|
| 索引重組 | ❌ 保留原鍵值,產生「洞」 | ✅ 數值索引重新排序 (0,1,2...) |
| 關聯陣列 | ✅ 保留鍵名 | ⚠️ 字串鍵會被保留,數值鍵重排 |
| 回傳值 | 無 | 被移除的元素陣列 |
| 多元素刪除 | 需迴圈 | 單次呼叫指定 offset/length |
| 效能 (大陣列) | O(1) 單元素 | O(n) 需重建陣列 |
$a = ['red', 'green', 'blue', 'yellow'];
unset($a[1]); // 刪除 'green'
var_dump($a);
/*
array(3) {
[0]=> string(3) "red"
[2]=> string(4) "blue" // 索引跳過 1
[3]=> string(6) "yellow"
}
*/
echo $a[2]; // "blue" (非 "yellow")
echo $a[1]; // Notice: Undefined offset
count($a); // 3
⚠️ 後續若用 for ($i=0; $iforeach 或先 array_values($a) 重排。
$a = ['red', 'green', 'blue', 'yellow'];
$removed = array_splice($a, 1, 1); // 從索引 1 刪除 1 個
var_dump($a); // [0=>red, 1=>blue, 2=>yellow] 索引連續
var_dump($removed); // [0=>green] 可取得被刪元素
// 刪除多個連續元素
$b = range('a', 'z');
array_splice($b, 5, 3); // 刪除 f,g,h (索引 5,6,7)
// 同時刪除並插入新元素 (替換)
$c = [1,2,3,4,5];
array_splice($c, 1, 2, ['x', 'y']); // 刪除 2,3 插入 x,y
// 結果: [1, 'x', 'y', 4, 5]
// 關聯陣列刪除 (保留鍵名)
$assoc = ['a'=>1, 'b'=>2, 'c'=>3];
unset($assoc['b']); // 建議用 unset
// array_splice($assoc, 1, 1) 會導致數值索引重排,字串鍵保留但順序改變
array_splice()unset($arr[$key])unset()array_splice()unset() 最後 array_values() 重排function array_delete(&$array, $keys, $reindex = true) {
foreach ((array)$keys as $key) {
unset($array[$key]);
}
if ($reindex && array_is_list($array)) { // PHP 8.1+ array_is_list
$array = array_values($array);
}
return $array;
}
// 使用
$data = ['a','b','c','d','e'];
array_delete($data, [1,3]); // 刪除 b,d -> ['a','c','e'] 索引 0,1,2
理解兩者差異,能避免「索引斷層導致迴圈錯誤」這類隱性 Bug,寫出更健壯的陣列操作代碼。