在 Laravel 中,我如何非静态地启动 trait

In Laravel, how can I boot trait non-statically

在Laravel中我们只有这种静态引导特征的方式有什么原因吗:

static function bootMyTrait ()
{...}

有什么方法可以引导特征并在引导函数中包含模型实例吗?像这样:

function bootMyTrait ()
{
    if ($this instanceOf awesomeInterface)
    {
        $this->append('nice_attribute');
    }
}

我需要这个AF,好久没找到解决方法

好吧,似乎没人关心 :D

好消息是,在 15 分钟内,我已经在 基本模型:

中解决了我的问题
public function __construct(array $attributes = [])
{

    foreach (class_uses_recursive($this) as $trait)
    {
        if (method_exists($this, $method = 'init'.class_basename($trait))) {
            $this->{$method}();
        }
    }

    parent::__construct($attributes);
}

编辑

不要依赖特性,而是使用 Eloquent 的访问器和修改器。例如,在 User 模型上定义以下方法:

// Any time `$user->first_name` is accessed, it will automatically Uppercase the first letter of $value
public function getFirstNameAttribute($value)
{
    return ucfirst($value);
}

这会将 $user->first_name 属性附加到模型。通过在方法名称前加上 get 前缀和 Attribute 后缀,你告诉 Eloquent,嘿,这是我模型上的一个实际属性。它不需要存在于 table.

另一方面,您可以定义一个修改器:

// Any string set as first_name will automatically Uppercase words.
public function setFirstNameAttribute($value)
{
    $this->attributes['first_name'] = ucwords($value);
}

这将应用您对 $value 所做的任何操作,然后再将其设置到 $attributes 数组中。

当然,您可以将这些应用于数据库中确实存在的属性 table。如果您有原始的、未格式化的数据,比如电话号码 1234567890,并且您想要应用国家代码,则可以使用访问器方法来屏蔽该号码,而无需修改数据库中的原始值。换句话说,如果你想对一个值应用标准格式,你可以使用一个 mutator 方法,这样你所有的数据库值都符合一个通用标准。

Laravel Accessor and Mutators

因为 Laravel 5.7 你可以使用 trait initializers,而不是 trait booters。我有同样的任务并且能够像这样解决它:

public function initializeMyTrait()
{
    if ($this instanceOf awesomeInterface)
    {
        $this->append('nice_attribute');
    }
}