想拿到数组的第一个键名,以前得用reset()配合key(),但这样会移动数组的内部指针。PHP 7.3专门加了array_key_first()来解决这个问题——直接返回数组的第一个键名,不改变原数组,也不移动指针。
语法格式
mixed array_key_first(array $array): mixed
参数说明:
| 参数 | 说明 | 必填? |
|---|---|---|
| array | 要操作的数组 | 必填 |
返回值:
-
数组不为空时,返回第一个键名
-
数组为空时,返回
null
老办法的问题
在PHP 7.3之前,获取数组第一个键名得这么写:
$first_key = key($array); // 但这样不行,key()不重置指针
reset($array);
$first_key = key($array);
// 指针被移动了,后续代码可能有影响
或者用array_keys()取所有键名再拿第一个:
$keys = array_keys($array);
$first_key = $keys[0] ?? null;
// 但这样会创建一个新数组,大数组时浪费内存
array_key_first()解决了这两个问题:不移动指针,不创建新数组。
示例1:关联数组
<?php
$student = [
"id" => 1001,
"name" => "张伟",
"score" => 85,
"class" => "软件工程"
];
$first_key = array_key_first($student);
echo "第一个键名:{$first_key}\n";
echo "对应的值:{$student[$first_key]}\n";
// 验证原数组指针没有被移动
echo "current()指向:" . current($student) . "\n";
?>
输出:
第一个键名:id
对应的值:1001
current()指向:1001
注意:current()仍然指向第一个元素,指针没有被array_key_first()影响。
示例2:索引数组
<?php
$colors = ["红色", "绿色", "蓝色", "黄颜色"];
$first_key = array_key_first($colors);
echo "第一个键名:{$first_key}\n";
echo "第一个值:{$colors[$first_key]}\n";
?>
输出:
第一个键名:0
第一个值:红色
索引数组的键名就是数字下标,第一个键名总是0(除非数组被重新索引过或不是从0开始)。
示例3:空数组
<?php
$empty = [];
$first_key = array_key_first($empty);
var_dump($first_key);
if ($first_key === null) {
echo "数组是空的\n";
}
?>
输出:
NULL
数组是空的
空数组返回null,需要做判断处理。
示例4:键名不是从0开始的索引数组
<?php
$data = [
5 => "第五个",
10 => "第十个",
15 => "第十五个"
];
$first_key = array_key_first($data);
echo "第一个键名:{$first_key}\n";
echo "第一个值:{$data[$first_key]}\n";
?>
输出:
第一个键名:5
第一个值:第五个
索引数组的键名如果不连续或者不从0开始,array_key_first()返回小的那个键名(按定义顺序,不是数值大小)。
个人经验分享
-
和array_key_last()是搭档
PHP 7.3同时引入了array_key_first()和array_key_last(),一个拿第一个键名,一个拿之后一个键名。 -
为什么不用reset() + key()?
-
reset()会移动数组内部指针,可能影响后续遍历 -
如果数组是空数组,
reset()返回false,key()也返回null,逻辑上要走更多判断 -
array_key_first()一行搞定,语义清晰
-
-
性能方面
array_key_first()是O(1)操作,不复制数组。对于超大数组,比array_keys($arr)[0]高效得多。 -
PHP 8.0+ 的改进
从PHP 8.0开始,array_key_first()的参数类型更严格,传非数组会报TypeError。
示例5:代码号学习编程场景
<?php
// 场景:动态表格展示,需要获取第一列的字段名
$table_data = [
"student_id" => "学号",
"student_name" => "姓名",
"student_score" => "成绩",
"student_grade" => "等级"
];
// 获取第一列的键名作为特殊处理的标识
$first_column = array_key_first($table_data);
echo "第一列字段名:{$first_column}\n";
echo "第一列显示名称:{$table_data[$first_column]}\n";
// 遍历所有列
foreach ($table_data as $key => $label) {
$is_first = ($key === $first_column);
echo ($is_first ? "[首列] " : " ") . "{$label} ({$key})\n";
}
?>
输出:
第一列字段名:student_id
第一列显示名称:学号
[首列] 学号 (student_id)
姓名 (student_name)
成绩 (student_score)
等级 (student_grade)
示例6:多个PHP版本的兼容写法
<?php
// 兼容PHP 7.3以下版本的写法
if (!function_exists('array_key_first')) {
function array_key_first(array $arr) {
foreach ($arr as $key => $value) {
return $key;
}
return null;
}
}
// 现在可以放心使用了
$data = ["apple" => 1, "banana" => 2, "cherry" => 3];
echo "第一个键名:" . array_key_first($data);
?>
如果项目还需要支持PHP 7.2及以下,可以用这个polyfill。
示例7:配合end()取首尾对比
<?php
$queue = [
"task_001" => "发送邮件",
"task_002" => "生成报告",
"task_003" => "清理缓存",
"task_004" => "备份数据库"
];
$first_task_key = array_key_first($queue);
$last_task_key = array_key_last($queue);
echo "第一个任务:{$queue[$first_task_key]} (键名: {$first_task_key})\n";
echo "之后一个任务:{$queue[$last_task_key]} (键名: {$last_task_key})\n";
?>
输出:
第一个任务:发送邮件 (键名: task_001)
之后一个任务:备份数据库 (键名: task_004)
本节课程知识要点
-
array_key_first()返回数组的第一个键名,不改变原数组 -
空数组返回
null -
PHP 7.3.0正式引入
-
相比
reset()+key():不移动指针 -
相比
array_keys($arr)[0]:不创建新数组,内存效率高 -
配合
array_key_last()可以快速获取首尾键名 -
低版本PHP可以自己实现polyfill