array_fill填复合类型时所有元素共享引用,标量值则各自独立;参数顺序为(start_index, count, value),易与范围混淆;关联键填充应优先用array_fill_keys。

array_fill 填的是值,不是引用
用 array_fill 批量生成相同值的数组时,如果填的是数组、对象或资源等复合类型,所有键指向的是同一份内存——改其中一个,全跟着变。这不是 bug,是 PHP 的值复制机制决定的。
- 填标量(
int、string、bool)完全安全,各自独立 - 填数组:用
array_fill+array_map或循环调用[]创建新实例 - 填对象:必须用循环配合
new或clone,array_fill无法满足需求
例如:array_fill(0, 3, ['x' => 1]) 返回的三个子数组共享同一引用,$arr[0]['x'] = 99 会同时影响 $arr[1] 和 $arr[2]。
起始键和长度参数容易搞反顺序
array_fill 的参数顺序是 (start_index, count, value),不是「范围」也不是「下标区间」。很多人误以为第二个参数是结束键,结果生成空数组或报错。
-
array_fill(2, 3, 'a')→ 键为2, 3, 4,不是2, 3 -
array_fill(-2, 3, 'b')→ 键为-2, -1, 0,负起始键合法但易被忽略 - 若
count为 0 或负数,返回空数组,不报错也不警告
常见错误现象:array_fill(0, 5, 'x') 想生成索引 0~4 的数组,结果对了;但换成 array_fill(0, 5, ['y']) 就踩上前面说的引用坑。
立即学习“PHP免费学习笔记(深入)”;
替代方案:array_fill_keys 更适合关联键填充
当你要按一组已知键名批量赋相同值,别硬套 array_fill 再重键——它只管数字索引。直接用 array_fill_keys,语义清晰、无歧义。
-
array_fill_keys(['a', 'b', 'c'], 0)→['a'=>0, 'b'=>0, 'c'=>0] -
array_fill无法处理字符串键,强行用array_values+array_combine是绕路 - 性能上,
array_fill_keys是原生实现,比手动循环快且内存更稳
注意:array_fill_keys 的第一个参数必须是数组,传 null 或非数组会触发 warning,不是静默失败。
和 array_pad、range + array_fill 一起用时的边界陷阱
有人想“先占位再覆盖”,混用 array_fill 和 array_pad,结果发现长度没对齐;或者用 range 生成键再 array_fill,却忘了 range 默认步长是 1。
-
array_pad(array_fill(0, 2, 0), 5, 0)→ 实际得到 5 个元素,但前两个是array_fill填的,后三个是array_pad补的,逻辑割裂 -
array_fill_keys(range(1, 3), 'x')→ 键是1,2,3;但range('a', 'c')在 PHP 8.1+ 才支持字符,旧版本会返回空 - 多维场景下,
array_fill不递归,填二维得嵌套调用或用array_map
真正需要动态键+固定值时,优先写个简单 foreach ——可读性、可控性、调试友好度都比拼凑原生函数高。











