该错误是php语言层面对魔术方法的限制,非phpenv等问题;因__get返回值拷贝而非引用,导致$obj['field'][]=等间接修改报错;应改用“取→改→赋值”方式。

这个 Notice 不是 phpEnv 的问题,改 phpEnv 配置没用。它本质是 PHP 语言层面对魔术方法行为的限制,从 PHP 5.2 起就存在,和运行环境(phpEnv、XAMPP、Docker、宝塔)完全无关。你看到它,说明代码里正试图对一个通过 __get 返回的数组做“间接修改”——比如 $obj['field'][] = 'x' 或 $obj->data['key'] = 'y'。
为什么 $model['xxx'][] = ... 会报错
ThinkPHP 模型(如 StudentCacheModel)继承自 think\Model,它把属性访问重载了:$model['field'] 实际调用的是 __get('field'),而该方法返回的是一个值拷贝(不是引用)。你再对这个拷贝做 [] = 操作,PHP 就没法把修改“回写”到原始数据里,于是抛出 Indirect modification of overloaded property 并静默丢弃修改。
- 错误写法:
$student['tags'][] = 'vip';→ 报错且不生效 - 错误写法:
$student['config']['level'] = 5;→ 同样报错 - 错误写法:
foreach ($student['roles'] as &$r) { $r['status'] = 1; }→ 可能触发 Notice
ThinkPHP 中最稳妥的改法:先取、再改、后赋值
别碰 [] 语法,走显式路径。这是兼容性最好、逻辑最清晰的方式,也避免意外修改底层缓存结构。
- 用数组方式读:
$data = $student['some_field']; - 安全修改:
$data[] = 'new_item';或$data['key'] = 'val'; - 显式写回:
$student['some_field'] = $data; - 记得保存:
$student->save();(如果字段需要持久化)
等价的属性写法(如果模型允许):$student->some_field = $data; $student->save();
分页场景下批量处理字段,用 each() 避免踩坑
分页结果集(Paginator 对象)里每个 $item 仍是模型实例,直接改 $item['field'][] 同样会报错。正确做法是用 each() 回调,在回调内部走“取→改→赋值”流程:
$res = Db::name('member')
->where($query)
->order('uid desc')
->paginate($param['pageSize'], false, ['page' => $param['page']])
->each(function ($item, $key) {
// ✅ 安全修改
$pwd = $item['password'];
$item['password'] = think_ucenter_decrypt($pwd, config('PWD_KEY'));
// ✅ 显式赋值回去(注意:这里是给 Paginator item 赋值,非模型 save)
return $item;
});
注意:each() 修改的是分页集合里的副本,不影响数据库;若需落库,得在循环里调用模型的 save()。
真正容易被忽略的是:这个错误在开发时可能被 error_reporting 屏蔽(比如只开 E_ERROR),上线后开启 E_NOTICE 或 E_ALL 就立刻暴露。别依赖环境“不报错”,要从写法上根除间接修改。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











