这不是语法错误,而是类型错配——PHP 7.1+ 拒绝将字符串隐式当作数组使用;常见于变量先赋字符串值(如 $area = '')后又以键名访问(如 $area['CN']),此时需用 is_array() 显式校验类型。

直接结论:这不是语法错误,而是类型错配——你正在用字符串当数组用,PHP 7.1+ 拒绝这种隐式转换。
为什么 Illegal string offset 突然报错
PHP 5.4 起就要求字符串下标必须是整数或整数型字符串(如 '123'),但真正严格拦截是在 PHP 7.1+。常见诱因是变量复用:同一变量先被赋值为字符串(如 $area = ''),后续又被当成数组写入(如 $area['CN'] = '中国西部')。低版本 PHP 会默默转成数组,新版本直接抛 Warning。
- 错误示例:
Warning: Illegal string offset 'AR' in test.php on line 24 - 根本原因:
$area当前是字符串类型,却用了键名'AR'去索引 - 不是数组键不存在(那是
Undefined index),而是“根本不是数组”
is_array() 判断必须加在访问前
不能只靠 isset() 或 array_key_exists(),它们对字符串也返回 false,但不会阻止 PHP 尝试用字符串当数组访问——报错就发生在访问那一刻。
- 错的写法:
if (isset($data['handler'])) { echo $data['handler']; }—— 若$data是字符串,isset()返回false,但前面的判断不阻止后续逻辑误用 - 对的写法:
if (is_array($data) && isset($data['handler'])) { echo $data['handler']; } - 更安全的写法(尤其处理外部数据):
$handler = is_array($data) ? ($data['handler'] ?? null) : null;
声明阶段就要定死类型,别依赖运行时自动转换
PHP 不会帮你把 '' 升级成 [],它只会报错。初始化时明确类型,比到处加判断更干净。
立即学习“PHP免费学习笔记(深入)”;
- 声明为空数组:
$area = [];或$area = array();(推荐前者) - 如果变量来自函数返回值,先确认返回类型:
var_dump(gettype($data));,别假设 - 模板文件里(如 Discuz! 的
1_post_newthread.tpl.php)出现Illegal string offset 'special',大概率是$post或类似变量本该是数组,但某处逻辑让它变成了字符串(比如拼接失败、缓存污染、JSON 解析出错)
容易忽略的连带问题:空字符串和 null 的陷阱
''、null、false 都可能被误判为“可当数组用”,但 PHP 7.1+ 对这三者一视同仁:都不是数组,用 ['key'] 访问就报 Illegal string offset。
- 检查
json_decode()结果:$data = json_decode($json, true);必须加true,否则返回对象,$obj['key']会触发此错误 - 数据库查询结果为空时:
$row = $pdo->fetch();可能返回false,直接$row['id']就崩 - 函数返回值未校验:
$config = load_config();若load_config()出错返回'',后续所有$config['db_host']全挂
最麻烦的点往往不在报错行本身,而在上游——那个让变量变成字符串的地方。盯住变量第一次被赋值的位置,比在报错行反复加 is_array() 更治本。



















