想知道数组里有没有某个键名?array_key_exists()就是干这个的。它检查指定的键是否存在于数组中,存在返回true,不存在返回false。
这个函数从PHP 4.0.7就有了。看似简单,但有不少细节需要注意。
语法格式
bool array_key_exists(string|int $key, array $array): bool
参数说明:
| 参数 | 说明 | 必填? |
|---|---|---|
| key | 要检查的键名(整数或字符串) | 必填 |
| array | 被检查的数组 | 必填 |
返回值: 键存在返回true,否则返回false。
isset()与array_key_exists()的区别
这是PHP开发者经常混淆的地方:
| 情况 | isset(arr[arr[key]) | array_key_exists(key,key,arr) |
|---|---|---|
| 键存在,值为null | false | true |
| 键存在,值为其他 | true | true |
| 键不存在 | false | false |
核心区别: isset()在值为null时会返回false,而array_key_exists()会返回true。
示例1:基础用法
<?php
$student = [
"name" => "张伟",
"score" => 85,
"class" => "软件工程3班"
];
if (array_key_exists("score", $student)) {
echo "score键存在,值为:{$student['score']}\n";
} else {
echo "score键不存在\n";
}
if (array_key_exists("address", $student)) {
echo "address键存在\n";
} else {
echo "address键不存在\n";
}
?>
输出:
score键存在,值为:85
address键不存在
示例2:null值的场景(关键区别)
<?php
$user = [
"name" => "代码号001",
"email" => null,
"phone" => "13800000000"
];
// array_key_exists - 键存在就返回true
if (array_key_exists("email", $user)) {
echo "array_key_exists:email键存在\n";
} else {
echo "array_key_exists:email键不存在\n";
}
// isset - 值为null时返回false
if (isset($user["email"])) {
echo "isset:email键存在且有值\n";
} else {
echo "isset:email键不存在或值为null\n";
}
echo "\nemail的实际值:";
var_dump($user["email"]);
?>
输出:
array_key_exists:email键存在
isset:email键不存在或值为null
email的实际值:NULL
这是array_key_exists()最独特的价值:区分"键不存在"和"键存在但值为null"。
示例3:索引数组的键名检查
<?php
$colors = ["红色", "绿色", "蓝色", "黄颜色"];
echo "检查索引0:" . (array_key_exists(0, $colors) ? "存在" : "不存在") . "\n";
echo "检查索引3:" . (array_key_exists(3, $colors) ? "存在" : "不存在") . "\n";
echo "检查索引5:" . (array_key_exists(5, $colors) ? "存在" : "不存在") . "\n";
?>
输出:
检查索引0:存在
检查索引3:存在
检查索引5:不存在
索引数组的键名就是数字下标。array_key_exists(0, $colors)检查下标0是否存在。
个人经验分享
-
什么时候用array_key_exists而不是isset?
-
键的值可能就是null,需要区分"值为null"和"键不存在"
-
从数据库或API获取的数据,某些字段允许null值
-
需要精确判断键是否在数组中定义过
-
-
什么时候用isset?
-
不需要区分null和不存在
-
追求性能(isset比array_key_exists快一点,因为它是语言结构不是函数)
-
需要同时检查变量是否存在且不为null
-
-
性能对比
// isset 略快 if (isset($arr['key'])) { ... } // array_key_exists 略慢 if (array_key_exists('key', $arr)) { ... }差别很小,除非在循环中调用几十万次。日常开发按语义选就行。
-
PHP 8.0+ 的 isset() 行为
PHP 8.0开始,isset($arr['key'])在键不存在时不会再触发"Undefined array key"警告,和之前一样安全。 -
NULL的实际场景
实际项目中,为什么会有null值?比如:-
用户注册了但还没填写手机号:
"phone" => null -
配置项显式设置为空:
"cache_enabled" => null -
数据库字段允许NULL,ORM映射过来就是null
-
示例4:代码号学习编程场景
<?php
// 场景:用户配置更新,需要区分"不更新"和"更新为null"
function updateUserConfig($userId, $newConfig, $currentConfig) {
foreach ($newConfig as $key => $value) {
// 使用array_key_exists来区分"不传"和"传null"
if (array_key_exists($key, $newConfig)) {
// 不管value是null还是其他值,都要更新
$currentConfig[$key] = $value;
echo "更新字段 {$key} 为:" . var_export($value, true) . "\n";
}
}
return $currentConfig;
}
$current = [
"name" => "张伟",
"email" => "zhang@test.com",
"phone" => "13800000000",
"memo" => "备注信息"
];
// 前端提交的数据:想清空phone字段,不修改memo字段
$submitted = [
"name" => "张伟伟",
"phone" => null
// 注意:没有memo字段
];
$updated = updateUserConfig(1, $submitted, $current);
echo "\n更新后的配置:\n";
print_r($updated);
?>
输出:
更新字段 name 为:'张伟伟'
更新字段 phone 为:NULL
更新后的配置:
Array
(
[name] => 张伟伟
[email] => zhang@test.com
[phone] =>
[memo] => 备注信息
)
如果用isset()判断,phone => null会被跳过,清空操作就失败了。array_key_exists()在这里是正确选择。
示例5:多维数组的键名检查
<?php
$data = [
"user" => [
"id" => 1001,
"profile" => [
"age" => 25,
"city" => "北京"
]
]
];
// 检查第一层键
echo "检查'user'键:" . (array_key_exists("user", $data) ? "存在" : "不存在") . "\n";
echo "检查'order'键:" . (array_key_exists("order", $data) ? "存在" : "不存在") . "\n";
// 检查深层键需要多次访问
if (array_key_exists("user", $data)) {
echo "检查'user.profile.age':";
echo (array_key_exists("age", $data["user"]["profile"] ?? []) ? "存在" : "不存在") . "\n";
}
?>
输出:
检查'user'键:存在
检查'order'键:不存在
检查'user.profile.age':存在
array_key_exists()只检查一层,不递归。
示例6:键名为数字字符串的情况
<?php
$arr = ["123" => "value"];
echo "检查字符串'123':" . (array_key_exists("123", $arr) ? "存在" : "不存在") . "\n";
echo "检查整数123:" . (array_key_exists(123, $arr) ? "存在" : "不存在") . "\n";
?>
输出:
检查字符串'123':存在
检查整数123:存在
PHP在数组键名中,字符串"123"和整数123被视为同一个键。这和isset()的行为一致。
本节课程知识要点
-
array_key_exists()检查数组中是否存在指定键名 -
和
isset()的核心区别:array_key_exists()不检查值是否为null -
值为null时,
array_key_exists()返回true,isset()返回false -
适用于需要区分"键不存在"和"键存在但值为null"的场景
-
只检查一层,不递归处理多维数组
-
从PHP 4.0.7开始可用
-
PHP 7.3+ 有
array_key_first()和array_key_last()获取首尾键名