array_is_list()判断数组键是否为从0开始的连续整数序列,空数组返回true;而is_array()仅检测变量是否为数组类型,不关心键结构。

array_is_list 判断的是「键是否连续从 0 开始」
它不看值,也不看是不是关联数组,只严格检查键:必须是 0, 1, 2, ..., count($array)-1 这样一个不多、一个不少、顺序严格的整数序列。空数组 [] 也返回 true,这是明确规定的。
- 键含字符串(如
'id'、'name')→ 直接false - 键跳号(如
[0 => 'a', 2 => 'b'])→false - 键从 1 开始(如
[1 => 'a', 2 => 'b'])→false - 键乱序(如
[1 => 'a', 0 => 'b'])→false - 键是字符串数字但非整型(如
['0' => 'a'])→false(因为'0'是 string,不是 int)
和 is_array 的根本区别在哪
is_array() 只回答「这东西是不是 array 类型」,不管结构;而 array_is_list() 是在确定是 array 的前提下,进一步判断「它是不是能安全当列表用」——比如能否被 json_encode() 输出为 JSON 数组(而非对象),或能否被 foreach 按自然顺序遍历时不意外错位。
-
is_array(['a','b'])→true,array_is_list(['a','b'])→true -
is_array(['k' => 'v'])→true,array_is_list(['k' => 'v'])→false -
is_array(null)→false,array_is_list(null)会报TypeError(参数类型约束)
PHP 8.1+ 中 json_encode 依赖它
PHP 8.1 起,json_encode() 内部用 array_is_list() 决定输出格式:返回 true 就输出 [...],否则输出 {...}。这意味着你不能靠「有没有字符串键」来预测 JSON 形式了,得真调用 array_is_list() 看结果。
- 旧写法:
json_encode(array_values($arr))强制转成列表 → 多余开销 - 新推荐:先
if (array_is_list($arr)) { ... }分支处理,避免无谓重建数组 - 注意:
array_values($arr)总是返回 list,但它会复制整个数组,大数据量时有性能代价
低版本 PHP 的安全 polyfill
如果你还在用 PHP array_keys() + range() 的 polyfill——它们新建两个数组,内存翻倍。用单次遍历的版本:
立即学习“PHP免费学习笔记(深入)”;
if (!function_exists('array_is_list')) {
function array_is_list(array $array): bool {
$i = 0;
foreach ($array as $k => $v) {
if ($k !== $i++) {
return false;
}
}
return true;
}
}
这个实现不分配额外内存,且行为和原生函数完全一致。唯一要注意的是:它不会对非 array 输入报错,而原生函数会因类型声明拒绝非 array 参数。
实际使用时,别把它当成「判断是否该用 for 循环」的依据——PHP 的 foreach 本身已足够健壮;它的真正价值在于接口契约校验、序列化控制和调试时快速识别数据结构意图。



















