Php 拉威尔雄辩-覆盖模型';s构造函数来更改属性

Php 拉威尔雄辩-覆盖模型';s构造函数来更改属性,php,laravel,eloquent,Php,Laravel,Eloquent,因此,我有一个页面模型,它扩展了雄辩的模型类。我试图重写构造函数,在这里我需要一些额外的逻辑。这就是我目前拥有的: class Page extends Model { public function __construct(array $attributes = []) { parent::__construct($attributes); $this->main_image = null; } } 但是当我调用Page::

因此,我有一个
页面
模型,它扩展了
雄辩的
模型
类。我试图重写构造函数,在这里我需要一些额外的逻辑。这就是我目前拥有的:

class Page extends Model
{

    public function __construct(array $attributes = [])
    {

        parent::__construct($attributes);
        $this->main_image = null;
    }

}
但是当我调用
Page::find(1)时,这似乎并没有将
main_图像
保存到
$this->attributes
属性中

我相信这是因为
Page::find
最终调用了
Model::newFromBuilder
,如下所示:

public function newFromBuilder($attributes = [], $connection = null)
{
    $model = $this->newInstance([], true);

    $model->setRawAttributes((array) $attributes, true);

    $model->setConnection($connection ?: $this->getConnectionName());

    return $model;
}
如您所见,它首先创建实例,然后设置属性,这意味着构造函数中设置的任何内容都会被忽略

是否有任何解决方法可以覆盖构造函数(或类似方法)来更改每个检索/创建的模型实例的属性?显然,我可以重写
newFromBuilder
newInstance
\uu-construct
和类似的方法,但这似乎非常粗糙且无法维护


谢谢

如果您只需要在检索或设置时能够自动修改模型的属性,那么请使用:

定义访问器

要定义访问器,请在模型上创建一个getFooAttribute方法,其中Foo是要访问的列的“studly”大小写名称。在本例中,我们将为first_name属性定义一个访问器。当尝试检索first_name属性的值时,Eloquent将自动调用访问器:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * Get the user's first name.
     *
     * @param  string  $value
     * @return string
     */
    public function getFirstNameAttribute($value)
    {
        return ucfirst($value);
    }
}
定义突变因子

要定义mutator,请在模型上定义setFooAttribute方法,其中Foo是要访问的列的“studly”大小写名称。同样,让我们为first_name属性定义一个mutator。当我们试图在模型上设置first_name属性的值时,将自动调用此mutator:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * Set the user's first name.
     *
     * @param  string  $value
     * @return void
     */
    public function setFirstNameAttribute($value)
    {
        $this->attributes['first_name'] = strtolower($value);
    }
}

在本例中,将使用值Sally调用setFirstNameAttribute函数。然后,mutator将对名称应用strtolower函数,并在内部$attributes数组中设置其结果值。

因此,基本上您希望在创建新元素时覆盖一个参数?你应该使用模型事件,尤其是“创建/创建”。重写只是一个例子,可能有多个参数重写,它们将被封装在if语句中。我将检查这些事件,如果我可以将它们应用于所有类,而不必为每个模型编写观察者类。谢谢您的模型没有
main\u image
字段有什么原因吗?在模型内部设置它的最终目标是什么?如果所有页面都有一个
main\u图像
,那么可能会有另一种方法来解决这个问题,可能会有更多的信息,如果所有页面都有一个
main\u图像
,则可以形成一种关系,这样您就可以执行
$page->main image->get()
这背后的原因是另一个问题的潜在解决方案:因此我想检查
$page->main\u image\u id
是否为空,将
$page->main\u image
设置为null,并且不调用关系方法
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * Set the user's first name.
     *
     * @param  string  $value
     * @return void
     */
    public function setFirstNameAttribute($value)
    {
        $this->attributes['first_name'] = strtolower($value);
    }
}
$user = App\User::find(1);

$user->first_name = 'Sally';