json_encode()将索引数组转为json数组是因为其严格判定:键必须全为整数且从0开始连续(如0,1,2),否则视为关联数组而输出对象;解决方法是编码前用array_values()重置键。

json_encode() 把索引数组转成 JSON 数组(即用 [...] 包裹),是因为它严格遵循 PHP 数组的结构特征来决定输出格式:只要数组是纯数字键、且键连续从 0 开始,就认定为“索引数组”,并编码为 JSON 数组。
这不是 bug,而是设计逻辑——JSON 本身没有“索引数组”概念,但 JavaScript 数组在语义上对应 PHP 的这种结构,所以 json_encode() 主动做了映射。
关键判断条件有两个,缺一不可:
- 所有键都是整数(或可转为整数的字符串,如
'0'、'1') - 键值构成一个从
0开始的连续序列:0, 1, 2, ..., n-1
比如:
$arr1 = ['a', 'b', 'c']; // 键是 0,1,2 → 输出 ["a","b","c"]
$arr2 = ['0'=>'a', '1'=>'b']; // 字符串数字键,仍被识别为索引 → ["a","b"]
$arr3 = [1=>'a', 2=>'b']; // 键从 1 开始,不连续(缺 0)→ 输出 {"1":"a","2":"b"}
$arr4 = [0=>'a', 2=>'b']; // 键不连续(缺 1)→ 输出 {"0":"a","2":"b"}
一旦破坏连续性(例如 unset($arr[0])、手动设置 $arr[5] = ...),PHP 内部就不再视其为“索引数组”,而归类为“关联数组”,于是 json_encode() 改用对象格式 {} 输出。
这也是为什么很多人遇到“删了元素后 JSON 变成对象”的困惑——根本原因不是 unset() 本身改变了类型,而是它让键变得稀疏,触发了 json_encode() 的判定逻辑。
如果需要确保始终输出数组,不管是否稀疏,可以在编码前重置键:
$array = array_values($array); // 强制重排为 0,1,2,... echo json_encode($array); // 总是 [...]
这个操作轻量、安全,适用于大多数 API 返回场景。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











