You need to enable JavaScript to run this app. Laravel Resource使用when实现条件资源项时报非对象属性获取错误
优惠活动
大模型
产品
解决方案
定价
更多

Laravel Resource使用when实现条件资源项时报非对象属性获取错误

为什么Laravel Resource的when写法会触发报错

核心原因拆解

  • $this->when()是Laravel Api Resource内置的条件输出方法,它的参数执行逻辑和你手写的三目运算完全不一样,直接照搬三目的传参写法必然会出问题。
  • 首先要搞懂PHP方法传参的基础规则:所有写在方法参数位置的表达式,都会在方法被调用前即时计算出结果,再传入方法内部。
    你写的$this->when($this->recup, $this->recup->test)这行,在真正进入when方法执行逻辑前,PHP就已经把第二个参数$this->recup->test算完了——不管第一个判断条件是不是为真,代码都会硬闯去读取$this->recup的test属性。如果这时候recup关联没有匹配到对应记录(值为null),就已经触发了非对象取属性的报错,根本轮不到when方法帮你做条件判断。
  • 你看到的具体报错Trying to get property 'value' of non-object,来源也和上面的传参逻辑直接相关:你提前算好传入的第二个参数值,会被when方法默认当成Resource响应实例处理——当判断条件为真时,when内部会尝试读取这个传入对象的value属性来组装响应。但你传进去的是普通的模型属性值、甚至是关联模型实例,根本不是Resource实例,没有value属性,自然就触发了这个报错。

为什么手写的三目运算可以正常运行

你写的$this->recup ? ($this->recup->test) : 'null'是典型的短路求值逻辑:

  • 代码会先判断$this->recup是不是有值
  • 只有当判断结果为真的时候,才会执行后面的$this->recup->test读取属性
  • 如果$this->recup是null,代码直接返回'null',根本不会触发对非对象取属性的操作
    这和when方法提前计算所有参数值的逻辑完全不同,所以手写三目可以稳定运行。

正确的when方法写法

when方法的设计初衷,就是让你把条件满足时要返回的内容、默认返回的内容,用无参闭包传进去,让Laravel在内部判断完条件之后,再去执行闭包里的代码读取对应值,从根源上避免提前求值的问题:

// 正确写法
'te' => $this->when(
    $this->recup,
    // 条件为真时才会执行这个闭包,读取对应属性
    fn () => $this->recup->test,
    // 条件为假时的默认值,同样可以包成闭包
    fn () => 'null'
),

这样写之后:

  • 传入when的只是几个闭包对象,PHP不会提前执行闭包里的代码
  • 等when内部判断完$this->recup确实有值的时候,才会调用对应闭包读取属性,不会出现对null取属性的问题
  • 因为闭包返回的是普通的属性值,不是Resource实例,when内部也不会尝试读取不存在的value属性,报错自然就消失了。

内容的提问来源于stack exchange,提问作者Larave

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.28 18:45:03