Laravel模型修改器?修改器如何工作?

laravel模型修改器?修改器如何工作?

Laravel模型修改器,简单来说,就是让你在从数据库获取数据后,或者将数据保存到数据库之前,对模型的属性进行一些“魔法”操作。它就像一个数据变形金刚,可以把数据库里存储的格式转换成你想要的格式,反之亦然。

修改器主要通过两个方法来工作:

get{属性名}Attribute

登录后复制登录后复制 和

set{属性名}Attribute

登录后复制登录后复制。前者在获取属性值时被调用,后者在设置属性值时被调用。

解决方案

修改器允许你在获取和设置模型属性时自定义逻辑。以下是一些使用场景和例子:

  • 格式化日期: 数据库里存储的是时间戳,但你想在前端展示成 "YYYY-MM-DD" 的格式。

    namespace App\Models;
    
    use Illuminate\Database\Eloquent\Model;
    
    class User extends Model
    {
        public function getCreatedAtAttribute($value)
        {
            return date('Y-m-d', strtotime($value));
        }
    
        public function setCreatedAtAttribute($value)
        {
            $this->attributes['created_at'] = strtotime($value);
        }
    }

    登录后复制

    这样,当你访问

    $user->created_at

    登录后复制 时,就会得到格式化后的日期字符串。当你设置

    $user->created_at = '2023-10-27'

    登录后复制 时,会自动转换为时间戳并存储到数据库。

  • 加密/解密数据: 比如用户的银行卡号,需要加密存储,解密后才能使用。

    namespace App\Models;
    
    use Illuminate\Database\Eloquent\Model;
    use Illuminate\Support\Facades\Crypt;
    
    class User extends Model
    {
        public function getBankAccountAttribute($value)
        {
            return Crypt::decryptString($value);
        }
    
        public function setBankAccountAttribute($value)
        {
            $this->attributes['bank_account'] = Crypt::encryptString($value);
        }
    }

    登录后复制

    这个例子使用了 Laravel 的

    Crypt

    登录后复制 Facade 来加密和解密数据。

  • 组合属性: 比如数据库里存储了

    first_name

    登录后复制 和

    last_name

    登录后复制,你想获取一个

    full_name

    登录后复制登录后复制 属性。

    namespace App\Models;
    
    use Illuminate\Database\Eloquent\Model;
    
    class User extends Model
    {
        public function getFullNameAttribute()
        {
            return $this->first_name . ' ' . $this->last_name;
        }
    }

    登录后复制

    注意,这个例子只有

    get

    登录后复制登录后复制 方法,没有

    set

    登录后复制登录后复制 方法,因为

    full_name

    登录后复制登录后复制 是一个只读属性,不能直接设置。

  • 类型转换: 将数据库中的字符串转换为布尔值,或者将数值转换为字符串。

    Interior AI

    Interior AI

    AI室内设计,上传室内照片自动帮你生成多种风格的室内设计图

    Interior AI58

    查看详情
    Interior AI

    namespace App\Models;
    
    use Illuminate\Database\Eloquent\Model;
    
    class Product extends Model
    {
        public function getIsActiveAttribute($value)
        {
            return (bool) $value;
        }
    
        public function setIsActiveAttribute($value)
        {
            $this->attributes['is_active'] = (int) $value;
        }
    }

    登录后复制

    这里,

    is_active

    登录后复制 在数据库中可能是 TINYINT 类型,通过修改器,我们可以在 PHP 代码中将其转换为布尔值,方便使用。

如何避免修改器中的无限循环?

这是个常见的问题。如果你在

get

登录后复制登录后复制 或

set

登录后复制登录后复制 方法中直接访问

$this->属性名

登录后复制,就会触发无限循环。正确的做法是使用

$this->attributes['属性名']

登录后复制 来访问原始属性值。

例如,错误的做法:

public function getEmailAttribute($value)
{
    return strtolower($this->email); // 错误!无限循环
}

登录后复制

正确的做法:

public function getEmailAttribute($value)
{
    return strtolower($this->attributes['email']); // 正确!
}

登录后复制

修改器和访问器有什么区别?什么时候应该使用它们?

实际上,在 Laravel 中,“修改器” 和 “访问器” 经常被放在一起讨论,甚至可以认为它们是同一个概念的不同方面。

get{属性名}Attribute

登录后复制登录后复制 通常被称为访问器,

set{属性名}Attribute

登录后复制登录后复制 被称为修改器。

  • 访问器 (Accessor): 用于在获取属性值时修改属性。
  • 修改器 (Mutator): 用于在设置属性值时修改属性。

什么时候使用它们呢? 当你需要对模型属性进行格式化、转换、加密/解密、组合等操作时,就应该使用修改器和访问器。 它们提供了一种简洁、优雅的方式来处理模型数据,避免在业务逻辑中重复编写相同的代码。

如何在 Eloquent 模型中使用类型转换 (Casting)?它和修改器有什么关系?

Eloquent 模型提供了类型转换 (Casting) 的功能,可以在模型中定义

casts

登录后复制 属性,自动将数据库中的数据转换为指定的数据类型。

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    protected $casts = [
        'is_admin' => 'boolean',
        'created_at' => 'datetime:Y-m-d H:i:s',
    ];
}

登录后复制

在这个例子中,

is_admin

登录后复制 字段会被自动转换为布尔值,

created_at

登录后复制 字段会被自动转换为

DateTime

登录后复制登录后复制登录后复制 对象,并格式化为指定的字符串格式。

那么,类型转换和修改器有什么关系呢?

  • 类型转换: 主要用于简单的数据类型转换,比如将字符串转换为布尔值、整数、浮点数、日期等。
  • 修改器: 更加灵活,可以执行复杂的逻辑,比如加密/解密、格式化、组合等。

如果只需要进行简单的数据类型转换,可以使用类型转换。如果需要执行复杂的逻辑,或者需要同时修改获取和设置行为,可以使用修改器。在某些情况下,也可以将两者结合使用。例如,可以使用类型转换将数据库中的字符串转换为

DateTime

登录后复制登录后复制登录后复制 对象,然后使用修改器对

DateTime

登录后复制登录后复制登录后复制 对象进行格式化。