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';