array_key_exists('key', $array) trả về true nếu mảng có khóa đó và false nếu không. Lưu ý thứ tự: khóa đứng trước, mảng đứng sau. Hàm trả về true ngay cả khi giá trị lưu ở khóa đó là null, và đây chính là điều duy nhất isset() không làm.
Để kiểm tra một giá trị thay vì một khóa, hãy dùng in_array().
array_key_exists vs isset
Cả hai đều kiểm tra một khóa. Chúng chỉ cho kết quả khác nhau khi giá trị là null: isset() coi giá trị null là "chưa được đặt", còn array_key_exists() báo đúng những gì thật sự có trong mảng.
0 và '' đều được cả hai coi là đã đặt; chỉ có null làm chúng khác nhau. Bạn cần hàm nào phụ thuộc vào ý nghĩa của null trong dữ liệu:
- Dùng
isset()khinullnghĩa là "không có giá trị". Đây là trường hợp phổ biến,isset()là một cấu trúc ngôn ngữ (nhanh hơn một chút), và nó nhận cả đường dẫn lồng nhau lẫn biến chưa định nghĩa mà không cảnh báo. - Dùng
array_key_exists()khinulllà một giá trị thật mà bạn phải phân biệt với khóa không tồn tại: một trường JSON được gửi lànull, một cột cơ sở dữ liệu có giá trịNULL, một tùy chọn được cố ý đặt lànullđể xóa nó.
Trang isset trình bày các cách dùng khác của nó, bao gồm kiểm tra nhiều biến cùng lúc.
Phân biệt null với khóa không tồn tại trong payload JSON
Một trường hợp điển hình mà chỉ array_key_exists() cho câu trả lời đúng: một API cập nhật bản ghi từ JSON. Trường được gửi là null nghĩa là "xóa nó", còn trường không được gửi nghĩa là "đừng động vào". isset() coi hai trường hợp này là một.
Nếu dùng isset($patch[$field]), số điện thoại sẽ vẫn còn, vì null trông giống như một trường không được gửi.
key_exists() là cùng một hàm
key_exists() là bí danh của array_key_exists(), còn giữ lại từ các phiên bản PHP đầu tiên. Cùng đối số, cùng kết quả. Hãy ưu tiên tên đầy đủ, vì đó là tên người đọc code mong đợi.
Kiểu của khóa: "1" và 1 là cùng một khóa
Khóa của mảng là số nguyên hoặc chuỗi, và một chuỗi chỉ chứa số nguyên thập phân thông thường sẽ được lưu dưới dạng số nguyên. Vì vậy array_key_exists('1', $arr) tìm thấy khóa 1, và ngược lại. Một chuỗi như '01' vẫn là chuỗi và là một khóa khác.
Kiểm tra khóa lồng nhau và nhiều khóa
array_key_exists() chỉ xét một cấp. Với một đường dẫn lồng nhau mà null không quan trọng, isset($a['x']['y']) kiểm tra mọi cấp cùng lúc. Với đường dẫn mà null có ý nghĩa, một hàm hỗ trợ ngắn sẽ đi qua từng cấp. Để kiểm tra nhiều khóa có đủ hay không, hãy so sánh bằng array_diff_key().
array_flip($required) biến danh sách tên thành các khóa để array_diff_key() so sánh chúng với các khóa của đầu vào; phần còn lại là danh sách các trường bị thiếu, sẵn sàng cho thông báo lỗi.
Đối tượng cần property_exists
PHP phiên bản cũ chấp nhận đối tượng trong array_key_exists(). PHP 8 thì ném ra TypeError. Với đối tượng, property_exists() kiểm tra một thuộc tính đã khai báo hoặc thuộc tính động (kể cả khi được đặt là null), còn isset($obj->prop) hoạt động giống isset() trên mảng.
Hai dòng cuối cho thấy một cách khác: get_object_vars() biến các thuộc tính truy cập được của đối tượng thành một mảng, sau đó bạn dùng được các hàm xử lý mảng.
Câu hỏi thường gặp
Vì sao isset trả về false trong khi array_key_exists trả về true?
Vì khóa đó chứa null. isset($arr['k']) chỉ là true khi khóa tồn tại và giá trị khác null, còn array_key_exists('k', $arr) là true mỗi khi khóa có trong mảng. Với mọi giá trị khác, kể cả 0, '' và false, cả hai đều cho cùng một câu trả lời.
key_exists trong PHP là gì?
Là bí danh của array_key_exists(). key_exists('id', $row) và array_key_exists('id', $row) hoạt động giống hệt nhau. Phần lớn code dùng tên dài hơn.
Làm sao kiểm tra một khóa lồng nhau có tồn tại trong PHP?
Kiểm tra từng cấp: isset($data['user']['address']['city']) kiểm tra cả đường dẫn cùng lúc và không bao giờ cảnh báo khi thiếu một cấp. Nếu giá trị null vẫn phải được tính là có, hãy đi qua đường dẫn bằng array_key_exists() từng cấp một.
Có dùng array_key_exists với đối tượng được không?
Không. Từ PHP 8.0, truyền một đối tượng vào sẽ ném ra TypeError. Dùng property_exists($obj, 'name') cho các thuộc tính đã khai báo, hoặc isset($obj->name).