PHP 8.0+ 中对 null 值进行数组下标访问(如 $arr['key'])会抛出 TypeError,因 PHP 8 严格化该操作;PHP 7 则静默返回 null。常见于 json_decode 失败返回 null 后直接下标访问,或函数漏 return 导致 null 被当数组用。安全做法是先 is_array() 再 isset(),或预设 $data = $data ?: []。

直接说结论:这个错误表示你试图对一个 null 值做数组下标访问(比如 $arr['key']),而 PHP 8.0+ 不再允许这种操作。它不是“变量未定义”,而是“变量有值,但值是 null”,且你把它当数组用了。
为什么 PHP 8 会报这个错,而 PHP 7 不报?
PHP 7 允许对 null 执行数组访问(返回 null,静默失败);PHP 8 把它升级为 TypeError,更严格地暴露逻辑缺陷。
- 常见触发场景:
$data = json_decode($json, true)返回null(比如 JSON 格式错误、空字符串、null字符串),后续却直接写$data['id'] - 另一个典型:函数本该返回数组,但某些分支漏了
return,实际返回null,调用方没检查就下标访问 - 注意:
isset($arr['key'])或empty($arr['key'])在$arr === null时也会触发同一错误——因为它们内部仍尝试读取$arr['key']
怎么安全地访问可能为 null 的数组?
核心原则:先确认变量是数组(或至少不是 null),再取值。不要依赖“看起来应该有值”。
- 用
is_array()+isset()组合:if (is_array($data) && isset($data['id'])) { $id = $data['id']; } - PHP 7.4+ 推荐用空合并运算符
??配合??左侧表达式本身可安全求值(但注意:它不解决$data['id']这一访问本身报错的问题)——所以得先确保$data不是null:$id = $data['id'] ?? null; // ❌ 错!$data 是 null 时这行就崩了 $id = $data['id'] ?? null; // ✅ 对,但前提是 $data 已确认为数组
- 更稳妥的写法(PHP 7.0+):
$id = $data['id'] ?? null; // 仅当 $data 是数组时才安全 // 所以应先兜底: $data = $data ?: []; // 或更精确: $data = is_array($data) ? $data : [];
json_decode 后忘记检查失败,是最常见的根源
json_decode($json, true) 在解析失败时返回 null,不是空数组,也不是 false。很多开发者只记得检查 false,却忽略 null。
立即学习“PHP免费学习笔记(深入)”;
- 正确做法:
$data = json_decode($json, true); if (json_last_error() !== JSON_ERROR_NONE || !is_array($data)) { // 解析失败或结果非数组,不能继续用 $data['xxx'] throw new InvalidArgumentException('Invalid JSON or not an object'); } - 或者一步到位(PHP 7.3+):
$data = json_decode($json, true); if ($data === null) { // 注意:必须用全等 ===,因为 json_decode 成功也可能返回 false(如 JSON 是布尔 false) } - 别用
empty($data)判断,因为empty(null)是true,但empty([])也是true,无法区分“解析失败”和“空对象”
真正容易被忽略的点是:这个错误往往藏在嵌套调用里,比如 get_user_data()['profile']['avatar'] —— 只要中间任意一层返回 null,整个链式访问就崩。务必把每层拆开检查,别贪一行代码的简洁。



















