PHP索引数组本质是整数键映射,访问必须用数字下标;关联数组键名会隐式类型转换,需警惕覆盖;foreach是唯一安全通用遍历方式;混合数组自动索引基于最大整数键。

索引数组用数字下标访问,但别误以为“值能当键用”
索引数组本质是整数键映射,比如 $list = ["a", "b", "c"] 等价于 array(0 => "a", 1 => "b", 2 => "c")。访问必须用 $list[0]、$list[1] 这类数字下标。
常见错误是写 isset($list["a"]) 或 $list["a"] ——这查的是键名为字符串 "a" 的元素,而索引数组根本没有这个键,结果总是 null 或触发 Notice: Undefined index。
- 要检查某个值是否存在,用
in_array("a", $list),不是isset() - 想获取键名(比如找
"b"在第几个位置),用array_search("b", $list),返回1 - 手动指定起始索引(如从 1 开始):
$list = [1 => "first", "second", "third"]→ 键为1, 2, 3
关联数组的键名会被强制类型转换,注意字符串数字和布尔值
PHP 对数组键做隐式转换:字符串 "8"、浮点数 8.0、布尔值 true 都会变成整数 8 或 1,导致键被覆盖。
例如:$arr = ["8" => "a", 8 => "b", true => "c"] 实际只保留一个元素:[8 => "b"](因为 "8" 和 8 都转成整数 8,后写入的覆盖前者;true 转成 1,但没冲突所以不显见)。
- 避免用带前导零的字符串作键(如
"08"),它不会被转成整数,但容易和8混淆 - 不要用
null、array、object当键,会报Illegal offset type - 想安全地保留原始键名语义?统一用字符串,且加引号:
$config["cache_ttl"]比$config[cache_ttl](未加引号会被当常量)更可靠
foreach 是唯一通用遍历方式,for 只适合纯索引数组
foreach 能安全处理所有数组类型——索引、关联、多维、混合键,且内部使用指针优化,性能比 for + count() 更好。
而 for 循环依赖 count($arr) 和连续整数索引,一旦数组被 unset() 或手动设了非连续键(如 $arr[0]="a"; $arr[5]="b"),for 就会漏掉或报错。
- 遍历关联数组取键值:
foreach ($user as $key => $value) - 遍历多维数组:
foreach ($data as $row) { foreach ($row as $col => $val) { ... } } - 需要修改原数组元素?加引用:
foreach ($arr as &$item) { $item .= "_mod"; },记得最后unset($item)防止意外引用残留
混合数组里数字键和字符串键共存,但自动索引规则容易踩坑
PHP 允许在同一个数组里混用数字键和字符串键,比如:$mixed = ["first", "second", "type" => "string", 10 => "tenth"]。它的键是 0, 1, "type", 10,不是连续的。
关键陷阱在于“下一个自动索引”的计算逻辑:它只看当前已有**整数键中的最大值**,再加 1。上面例子中最大整数键是 10,所以下次 $mixed[] = "new" 会赋给键 11,而不是你以为的 2 或 3。
- 如果想保持紧凑索引,用
array_values($mixed)重排数字键 - 用
array_keys($mixed, "second", true)可精确匹配值并返回对应键(第三个参数true启用严格比较) - 判断数组是否“纯索引”,不能只看
is_numeric(key),得用array_keys($arr) === range(0, count($arr)-1)
实际项目里最常出问题的,不是语法不会写,而是对“PHP 数组本质是有序映射”这个前提缺乏直觉——它既不是传统 C 数组,也不是 JS 对象,键的转换规则和自动索引行为必须亲手试过几次边界 case 才会真正记住。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











