如何在Laravel中为日期时间创建一个通用的getter / mutator?

时间:2017-09-28 10:39:50

标签: laravel getter mutators

我创建了一个,我认为它有效:

<?php

namespace App\Traits;

use Carbon\Carbon;

trait FormatDates
{

    public function setAttribute($key, $value)
    {
        parent::setAttribute($key, $value);

        if (strtotime($value))
            $this->attributes[$key] = Carbon::parse($value);
    }
}

但是在调用相关模型时存在问题。例如,如果您有文章和标签模型,并且希望获得如下所有标签:

$article->tags

因为getter mutator而返回null

如何解决这个问题?

更新17.11.2017

我找到了解决问题的方法。在语言环境中显示日期的最佳方法是使用此功能:

\Carbon\Carbon::setToStringFormat("d.m.Y H:i");

只需创建一个服务提供商或中间件,它将以您想要的格式显示所有$日期。没有必要做一个吸气剂。

2 个答案:

答案 0 :(得分:2)

基于此:https://laravel.com/api/5.5/Illuminate/Database/Eloquent/Concerns/HasAttributes.html#method_getAttribute

描述说:

  

获取普通属性(不是关系)。

幸运的是,下面还有另外两种方法叫做 getRelationValue getRelationshipFromMethod ,它显示为:

  

建立关系。

     

从方法中获取关系值。

分别

在您的示例中,您似乎正在调用关系。

我认为你在做普遍的getter / mutator时应该考虑它。

<强>更新

如果您检查代码,getAttribute也会调用getRelationValue方法。但它是功能的最后手段;如果既不是属性,也不具有mutator,或者是的方法。

这是存根:https://github.com/laravel/framework/blob/5.5/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php#L302

/**
 * Get an attribute from the model.
 *
 * @param  string  $key
 * @return mixed
 */
public function getAttribute($key)
{
    if (! $key) {
        return;
    }
    // If the attribute exists in the attribute array or has a "get" mutator we will
    // get the attribute's value. Otherwise, we will proceed as if the developers
    // are asking for a relationship's value. This covers both types of values.
    if (array_key_exists($key, $this->attributes) ||
        $this->hasGetMutator($key)) {
        return $this->getAttributeValue($key);
    }
    // Here we will determine if the model base class itself contains this given key
    // since we don't want to treat any of those methods as relationships because
    // they are all intended as helper methods and none of these are relations.
    if (method_exists(self::class, $key)) {
        return;
    }
    return $this->getRelationValue($key);
}

另一个更新

因为您已经改变了问题:

您可以将属性名称添加到$casts$dates数组(在模型中),这样Laravel会自动将其转换为Carbon实例访问它,像这样:

class Article extends Model {
    ...
    protected $dates = ['some_date_attribute`];

$casts

    ...
    protected $casts = ['some_date_attributes' => 'date'];

答案 1 :(得分:0)

你真的可以避免这种情况,它已经存在了!

您可以在模型类上执行

protected $dates = ['nameOfTheDateOrTimestampTypeField','nameOfAnotherOne'];
相关问题