Để xóa một phần tử khỏi mảng PHP theo khóa, dùng unset($array[$key]). Phần tử biến mất, các khóa còn lại giữ nguyên như cũ, và unset một khóa không tồn tại cũng không gây lỗi.
Hãy nhìn kết quả thứ hai: các khóa giờ là 0, 2, 3. unset không bao giờ đánh số lại.
Đánh lại chỉ số mảng sau khi unset
Một danh sách có khóa bị hổng sẽ gây rắc rối về sau: vòng lặp for ($i = 0; ...) gặp phải chỉ số bị thiếu, và json_encode ghi ra một đối tượng JSON thay vì một mảng. array_values() trả lại cho bạn các khóa liền mạch.
Xóa theo vị trí với array_splice
array_splice($array, $offset, $length) xóa $length phần tử bắt đầu từ vị trí $offset, đánh số lại các khóa và trả về những gì đã xóa. Offset âm được đếm từ cuối. Hàm này còn chèn được phần tử thay thế ngay trong cùng một lần gọi.
array_splice làm việc theo vị trí chứ không theo khóa: với mảng kết hợp, nó xóa theo vị trí trong thứ tự và giữ nguyên các khóa chuỗi. Trang array_slice so sánh nó với array_slice, hàm sao chép một phần mảng mà không thay đổi mảng gốc.
Xóa phần tử theo giá trị
array_diff($array, [$value]) trả về mảng không còn phần tử nào bằng $value, giữ nguyên khóa của các phần tử còn lại. Để chỉ xóa phần tử khớp đầu tiên, tìm khóa của nó bằng array_search rồi unset.
array_diff so sánh giá trị dưới dạng chuỗi, nên array_diff([1, "1", 2], [1]) xóa cả số nguyên lẫn chuỗi. Khi điều kiện phức tạp hơn "bằng giá trị này", hãy dùng array_filter với một callback.
Xóa phần tử đầu tiên hoặc cuối cùng
array_shift() xóa phần tử đầu tiên còn array_pop() xóa phần tử cuối cùng. Cả hai đều trả về phần tử đã xóa, rất tiện cho hàng đợi và ngăn xếp.
array_shift đánh số lại các khóa số từ 0. array_pop thì không cần, vì chỗ hổng nằm ở cuối.
Xóa nhiều khóa cùng lúc
unset nhận nhiều phần tử trong một lần gọi. Để xóa một danh sách khóa đang nằm trong một mảng, hãy đảo nó bằng array_flip() để các tên trở thành khóa, rồi truyền vào array_diff_key().
Lỗi thường gặp: unset với array_search khi giá trị không có
array_search trả về false khi không tìm thấy gì, và false khi dùng làm khóa mảng sẽ thành 0. Vì vậy dòng này xóa phần tử đầu tiên mỗi khi giá trị không có trong mảng:
Luôn lưu kết quả của array_search và so sánh với !== false trước khi dùng nó làm khóa. Viết if ($key) cũng chưa đủ: một phần tử khớp ở chỉ số 0 cũng là giá trị falsy.
Câu hỏi thường gặp
Làm sao xóa một phần tử khỏi mảng theo giá trị trong PHP?
Để xóa mọi lần xuất hiện, dùng array_diff($arr, ['value']). Để chỉ xóa lần đầu tiên, tìm khóa của nó rồi unset, nhớ kiểm tra là đã tìm thấy: $k = array_search('value', $arr); if ($k !== false) { unset($arr[$k]); }.
Làm sao đánh lại chỉ số mảng sau khi unset?
Bọc mảng trong array_values(): $arr = array_values($arr); đánh số lại các khóa từ 0. Hoặc xóa phần tử bằng array_splice($arr, $index, 1), hàm này tự đánh số lại cho bạn.
Làm sao xóa phần tử đầu tiên hoặc cuối cùng của mảng?
array_shift($arr) xóa và trả về phần tử đầu tiên, đồng thời đánh số lại các khóa số. array_pop($arr) xóa và trả về phần tử cuối cùng.
Có thể unset một phần tử bên trong vòng lặp foreach không?
Có. foreach ($arr as $k => $v) { if ($v < 0) { unset($arr[$k]); } } an toàn, vì foreach duyệt trên một bản sao của mảng trong khi bạn thay đổi mảng gốc. Các khóa vẫn bị hổng, nên hãy gọi array_values() sau đó nếu bạn cần một danh sách.
unset một khóa không tồn tại có gây lỗi không?
Không. unset($arr['missing']) không làm gì cả và không phát sinh cảnh báo, nên bạn không cần kiểm tra bằng isset trước.