为什么 Created_at 是一个对象?

刚刚在练习这个地方是时候,因为我没有写访问器,所以想先看看效果一直报错,发现字符串是不能调用diffForHumans,原谅我菜,因为我看上面created_at轻松调用,虽然我及时解决但还是有点不明白,为什么create_at是一个Carbon对象,我在auth下面的注册控制器和trait找了半天什么都没发现,哪里有这个解释?先谢为敬
file
file

《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
leo
最佳答案

Laravel 会自动把 created_atupdated_at 转成 Carbon 对象,如果你希望自定义字段也有这个特性有两个办法:

  1. protected $casts = ['last_active_at' => 'date'];
  2. protected $dates = ['last_active_at'];
5年前 评论
讨论数量: 4
leo

Laravel 会自动把 created_atupdated_at 转成 Carbon 对象,如果你希望自定义字段也有这个特性有两个办法:

  1. protected $casts = ['last_active_at' => 'date'];
  2. protected $dates = ['last_active_at'];
5年前 评论
  • @leo 总的回复非常有启发性,但这里我测试了一下,在这个例子中,需要注意的是,因为设置了Accessor,那么从数据库中返回的数据都是经过我们自己的代码处理的,因此eloquent就不会帮我们去进行这个转换,而需要我们自己去new carbon一下。测试代码如下:
  • app/Models/Traits/LastActivedAtHelper.php

    public function getLastActivedAtAttribute($value)
    {
        // 获取今日对应的哈希表名称
        $hash = $this->getHashFromDateString(Carbon::now()->toDateString());
    
        // 字段名称,如:user_1
        $field = $this->getHashField();
    
        // 三元运算符,优先选择 Redis 的数据,否则使用数据库中
        $datetime = Redis::hGet($hash, $field) ? : $value;
        //$datetime = $value;
        // 如果存在的话,返回时间对应的 Carbon 实体
        if ($datetime) {
            return $datetime;
            //return new Carbon($datetime);
        } else {
            // 否则使用用户注册时间
            return $this->created_at;
        }
    }
  • resources/views/users/show.blade.php 中增加一句:
    <?php dd($user->last_actived_at) ?>
  • 效果如下,可以看到返回的是日期字符串而不是carbon对象:
    file
  • getLastActivedAtAttribute 这个方法注释掉,再运行,就可以自动转换了:
    file
  • 因此,我的结论是:`如果自定义日期字段在没有定义该字段对应的accessor的前提下,那么就可以使用attribute-casting这个特性去自动转换为carbon对象”
5年前 评论
leo

Laravel 会自动把 created_atupdated_at 转成 Carbon 对象,如果你希望自定义字段也有这个特性有两个办法:

  1. protected $casts = ['last_active_at' => 'date'];
  2. protected $dates = ['last_active_at'];
5年前 评论
  • @leo 总的回复非常有启发性,但这里我测试了一下,在这个例子中,需要注意的是,因为设置了Accessor,那么从数据库中返回的数据都是经过我们自己的代码处理的,因此eloquent就不会帮我们去进行这个转换,而需要我们自己去new carbon一下。测试代码如下:
  • app/Models/Traits/LastActivedAtHelper.php

    public function getLastActivedAtAttribute($value)
    {
        // 获取今日对应的哈希表名称
        $hash = $this->getHashFromDateString(Carbon::now()->toDateString());
    
        // 字段名称,如:user_1
        $field = $this->getHashField();
    
        // 三元运算符,优先选择 Redis 的数据,否则使用数据库中
        $datetime = Redis::hGet($hash, $field) ? : $value;
        //$datetime = $value;
        // 如果存在的话,返回时间对应的 Carbon 实体
        if ($datetime) {
            return $datetime;
            //return new Carbon($datetime);
        } else {
            // 否则使用用户注册时间
            return $this->created_at;
        }
    }
  • resources/views/users/show.blade.php 中增加一句:
    <?php dd($user->last_actived_at) ?>
  • 效果如下,可以看到返回的是日期字符串而不是carbon对象:
    file
  • getLastActivedAtAttribute 这个方法注释掉,再运行,就可以自动转换了:
    file
  • 因此,我的结论是:`如果自定义日期字段在没有定义该字段对应的accessor的前提下,那么就可以使用attribute-casting这个特性去自动转换为carbon对象”
5年前 评论

@hustnzj 总结的高屋建瓴,但是源码层面就不知道了

5年前 评论

来来来,我来授人以鱼,在这里打个断点
file
然后进入Model基类的__get($key)方法,再就是一系列逻辑到了 HasAttributes.php
file
最后我们再来看看getDates()里到底是啥
file
会发现 created_at 和 updated_at其实是写死了的,不过Laravel也给了我们扩展的机会,这就是Leo说的$dates属性了

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!