You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel5.5中created_at访问器调用diffForHumans报错问题咨询

嘿,这两个Laravel 5.5的问题我刚好踩过类似的坑,给你详细拆解下:

问题1:为何模型访问器中的diffForHumans可能被忽略?

这种情况通常是以下几个原因导致的,你可以逐一排查:

  • 访问器命名不规范:Laravel对访问器的命名有严格要求,必须是get[字段名首字母大写]Attribute的格式。比如要处理created_at字段,访问器得叫getCreatedAtAttribute,如果名字写错了,框架根本识别不到这个访问器,自然不会执行里面的diffForHumans()逻辑。
  • 没有正确处理字段值:如果访问器里没有把原始值转换成Carbon实例就调用方法,或者处理过程中丢失了值,那效果肯定出不来。正确的做法应该是先解析原始值为Carbon对象,再调用diffForHumans():
    public function getCreatedAtAttribute($value)
    {
        return \Carbon\Carbon::parse($value)->diffForHumans();
    }
    
  • 模型$dates属性未包含目标字段:虽然Laravel 5.5默认会把created_at和updated_at自动转为Carbon实例,但如果你自定义了$dates数组却没加这个字段,原始值就是普通字符串,访问器里的处理就会失效甚至报错。
  • 访问器被其他逻辑覆盖:比如你没把访问器对应的属性加入$appends数组,导致序列化(比如API返回、toArray())时看不到效果;或者有模型观察者、其他自定义方法修改了字段返回值,覆盖了访问器的逻辑。
问题2:定义created_at访问器时抛出「Call to a member function diffForHumans() on null」,但视图直接调用正常?

这个问题的核心是递归调用访问器导致的null,我之前也栽过这个跟头!

当你定义getCreatedAtAttribute()访问器时,如果在方法里用$this->created_at获取值,这会再次触发这个访问器,形成无限递归,最后返回null,自然就会报错说在null上调用diffForHumans()。

而你在视图里直接用$task->created_at->diffForHumans()正常,是因为默认情况下Laravel已经把created_at自动转为Carbon实例了,这时候调用的是Carbon原生方法,并没有触发你的自定义访问器。

解决方法很简单,直接从模型的$attributes数组里取原始值,避免递归:

use Carbon\Carbon;

public function getCreatedAtAttribute()
{
    return Carbon::parse($this->attributes['created_at'])->diffForHumans();
}

另外还有两个小概率原因可以排查:

  • 你自定义了模型的$dates数组,但没包含created_at,导致原始值不是Carbon实例(不过这种情况视图里直接调用也会报错,所以可能性很低);
  • 数据库中created_at字段存在null值(但你说视图里正常,所以这个概率也不大)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:03:18