繁体   English   中英

在Laravel中扩展访问器和修改器

[英]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变量,该变量将对数据库中的数据encryptdecrypt ,因此,为此我在模型内的encrypt variable添加了accessormutator

<?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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM