Bạn muốn bỏ một mã khỏi danh sách nhưng phần tử đầu tiên lại biến mất dù mã cần tìm không tồn tại. Lỗi có thể nằm ở cách nối array_search với unset: kết quả tìm kiếm không phải lúc nào cũng là một khóa hợp lệ. Bài này trình bày cách tách bước tìm, kiểm tra và cập nhật mảng.
1. Kết quả là khóa, không phải giá trị
Theo tài liệu PHP về array_search, hàm trả về khóa của giá trị khớp đầu tiên, hoặc false khi không tìm thấy. Tham số thứ ba đặt thành true yêu cầu so sánh cả kiểu dữ liệu.
$codes = ['START', 'REVIEW', 'DONE'];
var_dump(array_search('START', $codes, true)); // int(0)
var_dump(array_search('MISSING', $codes, true)); // bool(false)
Khóa số 0 là kết quả thành công. Vì vậy, kiểm tra if ($key) sẽ bỏ sót trường hợp này. Dùng $key !== false để xác định đã tìm thấy; dùng $key === false cho nhánh không tìm thấy.
2. Không đưa kết quả chưa kiểm tra vào unset
Ví dụ dưới đây là cách viết cần tránh, không phải đoạn mã để áp dụng:
// Khong an toan khi khong tim thay:
unset($codes[array_search('MISSING', $codes, true)]);
Khi kết quả là false, việc dùng nó làm khóa mảng có thể nhắm tới khóa số 0. Hãy tách rõ ba bước để nhánh thất bại không trở thành một thao tác sửa dữ liệu:
$codes = ['START', 'REVIEW', 'DONE'];
$key = array_search('MISSING', $codes, true);
if ($key !== false) {
unset($codes[$key]);
}
// $codes van giu nguyen ba phan tu.
Trong ứng dụng thật, không tìm thấy có thể là một kết quả bình thường hoặc một lỗi nghiệp vụ. Chọn cách trả kết quả hay báo lỗi theo hợp đồng của hàm, thay vì tự ý xóa một phần tử khác để tiếp tục.
3. Khóa chuỗi và giá trị trùng cần được xử lý có chủ đích
$states = [
'ticket-a' => 'open',
'ticket-b' => 'closed',
'ticket-c' => 'open',
];
$key = array_search('open', $states, true);
// $key la 'ticket-a', khong phai 0 va khong phai 'open'.
Đừng ép kết quả thành số nguyên nếu mảng sử dụng khóa chuỗi. Cũng đừng hiểu một lần tìm kiếm là đã xác định toàn bộ phần tử trùng. Nếu nghiệp vụ yêu cầu tác động đến tất cả mục đang mở, cần một bước duyệt riêng và kiểm thử đúng tập mục tiêu.
Với thao tác có ảnh hưởng lớn, ví dụ cập nhật nhiều bản ghi, nên thu thập danh sách khóa trước, kiểm tra phạm vi rồi mới thực hiện thay đổi. Một ví dụ mảng trong bộ nhớ không thay thế phân quyền hay giao dịch khi ghi cơ sở dữ liệu.
4. Strict không thay thế chuẩn hóa đầu vào
$ids = [12, 24];
var_dump(array_search('12', $ids, true)); // bool(false)
var_dump(array_search(12, $ids, true)); // int(0)
Nếu ID từ request là chuỗi còn danh sách dùng số nguyên, hãy xác định quy tắc đầu vào trước. Không tắt strict chỉ để kết quả trở thành khớp. Việc chấp nhận chuỗi số, khoảng trắng hoặc số có số 0 ở đầu là quyết định của ứng dụng và cần validation rõ ràng.
5. Kiểm tra cả trạng thái mảng sau thao tác
Một bộ test chỉ kiểm tra khóa tìm được vẫn có thể bỏ sót lỗi ở bước cập nhật. Hãy so sánh mảng cuối cùng với kết quả mong đợi cho từng tình huống:
- Giá trị nằm ở khóa 0: tìm thành công và chỉ sửa đúng phần tử đó.
- Không tìm thấy: mảng giữ nguyên, hoặc nhận lỗi nghiệp vụ đã quy định.
- Khóa chuỗi: giữ nguyên danh tính khóa, không ép sang số.
- Có nhiều giá trị giống nhau: hành vi một mục hay tất cả mục phải rõ ràng.
- Chuỗi số và số nguyên: kết quả đúng với quy tắc kiểu dữ liệu.
- Mảng rỗng: không tạo thêm hoặc xóa nhầm dữ liệu.
Kết luận: Giữ kết quả array_search trong một biến, so sánh tường minh với false và chỉ sử dụng khóa sau khi xác nhận thành công. Cách viết dài hơn một dòng nhưng làm rõ ranh giới giữa tìm kiếm thất bại và thay đổi dữ liệu.




Chưa có bình luận. Hãy là người đầu tiên chia sẻ ý kiến.