【问题标题】:In Laravel, how can I boot trait non-statically在 Laravel 中,如何非静态启动 trait
【发布时间】:2023-03-20 12:02:02
【问题描述】:

有什么理由让我们在 Laravel 中只有这种静态方式来启动 trait:

static function bootMyTrait ()
{...}

有什么方法可以引导 trait 并在引导函数中有模型实例?像这样:

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

我需要这个AF,很久没找到解决办法。

【问题讨论】:

  • 你能重新表述一下这个问题吗?我无法弄清楚你在问什么。
  • @JonStirling 哦,抱歉,问题中有问题和错别字。修复它们。我希望现在更清楚了。

标签: php laravel model eloquent traits


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    好吧,似乎没有人关心: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,嘿,这是我模型上的实际属性。它不需要存在于桌子上。

    另一方面,您可以定义一个 mutator:

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

    这会将您所做的任何事情应用于$value,然后再将其设置到$attributes 数组中。

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

    Laravel Accessor and Mutators

    【讨论】:

    • 我很好奇,在非静态上下文中需要它的用例是什么?
    • @btl 如果您查看我的问题,您可以看到确切的用例:将属性附加到 eloquent。如果你对 Laravel 的了解不多,那么在普通的 PHP 用例中,可能会向对象添加必要的属性,或者更改其属性的值(例如,如果某些条件,如“实现接口”为真)。现在我想问你——这些不是合法的用例吗?我做错了什么傻事吗?
    • 是的,您希望使用模型访问器,而不是使用特征。我会用一个例子来编辑你的答案。
    • 现在就来看看答案吧。比使用特征更容易和更清洁。
    • @btl 哦,谢谢伙计。但是,我的意图是使用 trait + 接口逻辑:基本模型使用 trait,任何其他模型都可以扩展它。然后,如果某些特定模型应该实现特征逻辑,请编写“实现 SomeInterface”。接下来,在 initSomeTrait 中检查模型是否正在实现 SomeInterface,如果是,则附加必要的属性并做一些其他的事情。也许我一开始没有说清楚,我的错。但是它超出了问题的范围:) 无论如何,谢谢兄弟!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-27
    • 2022-01-19
    • 1970-01-01
    • 2018-04-17
    • 2011-09-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多