PHP对象属性严格比较会导致对象所有属性丢失?
奇怪的PHP严格比较导致Laravel模型属性清空问题
环境信息
- PHP 8.3.2-1+020240120.16+debian111.gbpb43448
- Laravel Framework 11.4.0
- MySQL 8.0.33-0ubuntu0.20.04.2
问题背景
编辑Post模型时,提交表单调用update方法的路由模型绑定正常,能正确触发控制器方法。但PostController@update中通过PostPolicy的edit方法验证权限时,预期用户可编辑自己的帖子,实际却总是进入无权限的else分支。
问题详情
在PostPolicy的edit方法中,使用严格比较符===对比$post->user_id与$user->id时出现诡异现象:
- 比较前
$post属性值正常,但进入if分支后,$post的所有属性被清空为空值 - 添加
dd()调试时能正常进入if分支,移除dd()则跳转至else分支 - 反转比较逻辑后,依然总是执行“允许编辑所有帖子”的权限分支
排查建议
- 检查模型魔术方法:查看Post模型是否自定义了
__get、__set或__isset方法,这类魔术方法可能在属性访问时触发意外逻辑,导致属性被清空。 - 使用原始数据库值比较:避免直接访问
$post->user_id,改用$post->getOriginal('user_id')获取数据库原始值进行严格比较,规避Eloquent属性访问器或延迟加载的干扰。 - 排查Policy的副作用代码:仔细检查edit方法的if分支,确认是否存在
$post->fill([])、$post->forgetAttribute()这类会清空属性的代码,包括间接调用的情况。 - 临时切换非严格比较测试:将
===替换为==,观察是否还会出现属性清空的情况,以此缩小问题范围。 - 排查PHP环境干扰:禁用opcache、xdebug等第三方扩展后重新测试,或在干净的PHP环境中单独复现对比逻辑,排除环境因素导致的问题。
内容的提问来源于stack exchange,提问作者undefined
相关产品推荐
相关产品推荐

