[英]Extending accessor and mutators in Laravel
我正在尝试在Laravel 5.5
中开发一个小型应用程序,其中我制作了一个abstract model
,该abstract model
扩展了Laravel eloquent model
,如下所示:
<?php
use Illuminate\Database\Eloquent\Model;
class AbstractModel extends Model
{
}
现在,仅出于一般约定,我正在为此模型设置数据库连接:
<?php
use Illuminate\Database\Eloquent\Model;
class AbstractModel extends Model
{
/**
* Defining connection for database
*
* @var string
**/
protected $connection='mysql';
}
我创建了自己的模型,扩展了这个abstract class
:
<?php
use Illuminate\Database\Eloquent\SoftDeletes;
class Posts extends AbstractModel
{
use SoftDeletes;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'unique_id', 'title', 'contents'
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'id'
];
}
通过默认定义,我们知道它将具有mysql的数据库连接,类似的fillable
定义用于批量分配。 以类似的方式,我想制作一个encrypt
变量,该变量将对数据库中的数据encrypt
和decrypt
,因此,为此我在模型内的encrypt variable
添加了accessor
和mutator
:
<?php
use Illuminate\Database\Eloquent\SoftDeletes;
class Posts extends AbstractModel
{
use SoftDeletes;
/**
* The attributes that will have encryption.
*
* @var array
*/
protected $encryption = ['unique_id', 'title', 'contents'];
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'unique_id', 'title', 'contents'
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'id'
];
}
并将其配置回我的abstract model
:
<?php
use Illuminate\Database\Eloquent\Model;
class AbstractModel extends Model
{
/**
* Defining connection for database
*
* @var string
**/
protected $connection='mysql';
/**
* Defining encryption
*
* @var array
**/
protected $encryption = [];
public function setAttributes()
{
foreach ($this->encryption as $attributes)
{
$this->attributes[$attributes] = Crypt::encryptString($this->attributes[$attributes]);
}
}
public function getAttributes()
{
foreach ($this->encryption as $attributes)
{
$this->attributes[$attributes] = Crypt::decryptString($this->attributes[$attributes]);
}
}
}
我认为我的方法是错误的,因为没有对这些属性进行加密或解密,我可以看到发送来创建行的数据存储在数据库中,没有任何加密,并且也以相同的方式进行了检索。
更重要的是,我想用一个用例,在我加密这些字段的同时,它们的属性访问器或mutator在它们自己的模型中被调用,例如:
<?php
use Illuminate\Database\Eloquent\SoftDeletes;
class Posts extends AbstractModel
{
use SoftDeletes;
/**
* The attributes that will have encryption.
*
* @var array
*/
protected $encryption = ['unique_id', 'title', 'contents'];
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'unique_id', 'title', 'contents'
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'id'
];
public function setTitleAttributes($value)
{
return ucfirst($value);
}
public function getTitleAttributes($value)
{
return ucfirst($value)
}
}
欢迎任何反馈意见。 谢谢。
首先,雄辩的模型具有setAttribute()
和getAttribute()
方法,而不是setAttributes()
和getAttributes()
。
其次,针对这种情况。 我宁愿使用Eloquent的event 。 因为只有在您动态访问属性时才触发setAttribute()
或getAttribute()
方法,例如: $post->title
。
您可以在saving
事件时加密属性。 然后使用retrieved
事件将其解密。
<?php
namespace App;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Database\Eloquent\Model;
abstract class AbstractModel extends Model
{
protected $connection = 'mysql';
protected $encryption = [];
protected static function boot()
{
parent::boot();
// When being retrieved, decrypt the attributes.
static::retrieved(function ($instance) {
foreach ($instance->encryption as $encryptedKey) {
$instance->attributes[$encryptedKey] = Crypt::decryptString($instance->attributes[$encryptedKey]);
}
});
// When saving (could be create or update) the modal, encrypt the attributes.
static::saving(function ($instance) {
foreach ($instance->encryption as $encryptedKey) {
$instance->attributes[$encryptedKey] = Crypt::encryptString($instance->attributes[$encryptedKey]);
}
});
// Once it's saved, decrypt it back so it's still readble.
static::saved(function ($instance) {
foreach ($instance->encryption as $encryptedKey) {
$instance->attributes[$encryptedKey] = Crypt::decryptString($instance->attributes[$encryptedKey]);
}
});
}
}
当您决定使用此方法时,请勿同时覆盖setAttribute()
和getAttribute()
方法。 因为它很可能会双重加密/解密属性。
另外,它应该是setTitleAttribute()
和getTitleAttribute()
单数形式。 在setTitleAttribute()
您应该更改title
属性; 不返回预期值。 我也看不到大写title
的目的,因为无论如何它将被加密。
<?php
namespace App;
class Post extends Model
{
protected $encryption = ['unique_id', 'title', 'contents'];
protected $fillable = ['unique_id', 'title', 'contents'];
// Expected to mutate the title attribute.
public function setTitleAttribute($value)
{
$this->attributes['title'] = ucfirst($value);
}
public function getTitleAttribute($value)
{
return ucfirst($value);
}
}
希望这能给您一些想法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.