PHP 8.1+ 应用 array_is_list() 反推:true 为索引数组,false 且 is_array() 为关联数组;低版本用 is_array() + array_keys() 遍历判断非整型键。

怎么用 is_array() 和 array_keys() 判断关联数组
PHP 没有原生函数直接返回“这是关联数组”,但可以组合判断。核心思路是:先确认是数组,再检查键是否全为字符串(或存在非数字键)。is_array() 必须放在最前面,否则对 null、字符串等调用会出错。
常见错误是只用 array_values($arr) === $arr,这在稀疏数字索引(如 [0 => 1, 2 => 3])下会误判为关联数组——其实它仍是索引数组。
- 安全做法:先
if (!is_array($arr)) return false; - 再遍历键:
foreach (array_keys($arr) as $k) { if (!is_int($k)) return true; },遇到任意一个非整型键就认定为关联数组 - 注意:PHP 7.4+ 中
"0"、"1"这类字符串键会被自动转为整型索引,所以实际中更推荐用array_is_list()反向判断(见下节)
PHP 8.1+ 推荐用 array_is_list() 反推
array_is_list() 是 PHP 8.1 引入的内置函数,专门判断是否为「连续、从 0 开始的整数索引数组」。它比手写循环更可靠,且处理了隐式类型转换边界情况(比如键为 "0" 或 0.0)。
如果你的目标只是“区分索引数组和关联数组”,那么:
立即学习“PHP免费学习笔记(深入)”;
-
array_is_list($arr) === true→ 是索引数组 -
array_is_list($arr) === false且is_array($arr)→ 大概率是关联数组(或稀疏/乱序数字键数组) - 注意:
array_is_list([1, 2, 3])返回true,array_is_list([0 => 1, 1 => 2, 2 => 3])也返回true,但array_is_list(['a' => 1])或array_is_list([1 => 1])都返回false
为什么不用 json_encode() 或正则匹配键名
有人用 json_encode($arr) 看输出是否含 "key": 结构,或者用 preg_match('/"[\w]+":/', json_encode($arr)),这完全不可靠:
-
json_encode()会把所有数字键转成字符串([0=>1]编码后是{"0":1}),导致误判 - 如果数组值本身含双引号或冒号(如
['name' => 'foo:bar']),正则会崩溃或漏判 - 性能差:序列化整个数组开销大,尤其大数组时明显拖慢
- 根本问题:这不是类型判断,是语义误用——JSON 格式不反映 PHP 内部键类型
实际项目中该选哪个方法
取决于你的 PHP 版本和容忍度:
- PHP 8.1+:无条件用
array_is_list()反推,简洁、标准、少 bug - PHP 7.4–8.0:用
array_keys()+ 类型判断,但要加is_numeric($k) && intval($k) == $k来兼容字符串数字键 - PHP stdClass 表示结构体,数组只用于列表;或加注释/类型提示(
@var array) - 最容易被忽略的一点:很多所谓“关联数组”其实是配置数组(如
['host' => 'localhost', 'port' => 3306]),这类场景建议直接用isset($arr['host'])检查关键键,比判断“是不是关联数组”更有业务意义











