翻译进度
16
分块数量
1
参与人数

属性修改器 / 类型转换

这是一篇协同翻译的文章,你可以点击『我来翻译』按钮来参与翻译。


Eloquent: Mutators & Casting

Introduction

Accessors, mutators, and attribute casting allow you to transform Eloquent attribute values when you retrieve or set them on model instances. For example, you may want to use the Laravel encrypter to encrypt a value while it is stored in the database, and then automatically decrypt the attribute when you access it on an Eloquent model. Or, you may want to convert a JSON string that is stored in your database to an array when it is accessed via your Eloquent model.

Accessors and Mutators

Defining an Accessor

An accessor transforms an Eloquent attribute value when it is accessed. To define an accessor, create a protected method on your model to represent the accessible attribute. This method name should correspond to the "camel case" representation of the true underlying model attribute / database column when applicable.

In this example, we'll define an accessor for the first_name attribute. The accessor will automatically be called by Eloquent when attempting to retrieve the value of the first_name attribute. All attribute accessor / mutator methods must declare a return type-hint of Illuminate\Database\Eloquent\Casts\Attribute:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * Get the user's first name.
     */
    protected function firstName(): Attribute
    {
        return Attribute::make(
            get: fn (string $value) => ucfirst($value),
        );
    }
}

All accessor methods return an Attribute instance which defines how the attribute will be accessed and, optionally, mutated. In this example, we are only defining how the attribute will be accessed. To do so, we supply the get argument to the Attribute class constructor.

As you can see, the original value of the column is passed to the accessor, allowing you to manipulate and return the value. To access the value of the accessor, you may simply access the first_name attribute on a model instance:

use App\Models\User;

$user = User::find(1);

$firstName = $user->first_name;

[!NOTE]
If you would like these computed values to be added to the array / JSON representations of your model, you will need to append them.

Building Value Objects From Multiple Attributes

Sometimes your accessor may need to transform multiple model attributes into a single "value object". To do so, your get closure may accept a second argument of $attributes, which will be automatically supplied to the closure and will contain an array of all of the model's current attributes:

use App\Support\Address;
use Illuminate\Database\Eloquent\Casts\Attribute;

/**
 * Interact with the user's address.
 */
protected function address(): Attribute
{
    return Attribute::make(
        get: fn (mixed $value, array $attributes) => new Address(
            $attributes['address_line_one'],
            $attributes['address_line_two'],
        ),
    );
}

Accessor Caching

When returning value objects from accessors, any changes made to the value object will automatically be synced back to the model before the model is saved. This is possible because Eloquent retains instances returned by accessors so it can return the same instance each time the accessor is invoked:

use App\Models\User;

$user = User::find(1);

$user->address->lineOne = 'Updated Address Line 1 Value';
$user->address->lineTwo = 'Updated Address Line 2 Value';

$user->save();

However, you may sometimes wish to enable caching for primitive values like strings and booleans, particularly if they are computationally intensive. To accomplish this, you may invoke the shouldCache method when defining your accessor:

protected function hash(): Attribute
{
    return Attribute::make(
        get: fn (string $value) => bcrypt(gzuncompress($value)),
    )->shouldCache();
}

If you would like to disable the object caching behavior of attributes, you may invoke the withoutObjectCaching method when defining the attribute:

/**
 * Interact with the user's address.
 */
protected function address(): Attribute
{
    return Attribute::make(
        get: fn (mixed $value, array $attributes) => new Address(
            $attributes['address_line_one'],
            $attributes['address_line_two'],
        ),
    )->withoutObjectCaching();
}

Defining a Mutator

A mutator transforms an Eloquent attribute value when it is set. To define a mutator, you may provide the set argument when defining your attribute. Let's define a mutator for the first_name attribute. This mutator will be automatically called when we attempt to set the value of the first_name attribute on the model:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * Interact with the user's first name.
     */
    protected function firstName(): Attribute
    {
        return Attribute::make(
            get: fn (string $value) => ucfirst($value),
            set: fn (string $value) => strtolower($value),
        );
    }
}

The mutator closure will receive the value that is being set on the attribute, allowing you to manipulate the value and return the manipulated value. To use our mutator, we only need to set the first_name attribute on an Eloquent model:

use App\Models\User;

$user = User::find(1);

$user->first_name = 'Sally';

In this example, the set callback will be called with the value Sally. The mutator will then apply the strtolower function to the name and set its resulting value in the model's internal $attributes array.

Mutating Multiple Attributes

Sometimes your mutator may need to set multiple attributes on the underlying model. To do so, you may return an array from the set closure. Each key in the array should correspond with an underlying attribute / database column associated with the model:

use App\Support\Address;
use Illuminate\Database\Eloquent\Casts\Attribute;

/**
 * Interact with the user's address.
 */
protected function address(): Attribute
{
    return Attribute::make(
        get: fn (mixed $value, array $attributes) => new Address(
            $attributes['address_line_one'],
            $attributes['address_line_two'],
        ),
        set: fn (Address $value) => [
            'address_line_one' => $value->lineOne,
            'address_line_two' => $value->lineTwo,
        ],
    );
}

Attribute Casting

Attribute casting provides functionality similar to accessors and mutators without requiring you to define any additional methods on your model. Instead, your model's casts method provides a convenient way of converting attributes to common data types.

The casts method should return an array where the key is the name of the attribute being cast and the value is the type you wish to cast the column to. The supported cast types are:

  • array
  • AsUri::class
  • AsStringable::class
  • boolean
  • collection
  • date
  • datetime
  • immutable_date
  • immutable_datetime
  • decimal:<precision>
  • double
  • encrypted
  • encrypted:array
  • encrypted:collection
  • encrypted:object
  • float
  • hashed
  • integer
  • object
  • real
  • string
  • timestamp

To demonstrate attribute casting, let's cast the is_admin attribute, which is stored in our database as an integer (0 or 1) to a boolean value:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * Get the attributes that should be cast.
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'is_admin' => 'boolean',
        ];
    }
}

After defining the cast, the is_admin attribute will always be cast to a boolean when you access it, even if the underlying value is stored in the database as an integer:

$user = App\Models\User::find(1);

if ($user->is_admin) {
    // ...
}

If you need to add a new, temporary cast at runtime, you may use the mergeCasts method. These cast definitions will be added to any of the casts already defined on the model:

$user->mergeCasts([
    'is_admin' => 'integer',
    'options' => 'object',
]);

[!WARNING]
Attributes that are null will not be cast. In addition, you should never define a cast (or an attribute) that has the same name as a relationship or assign a cast to the model's primary key.

Stringable Casting

You may use the Illuminate\Database\Eloquent\Casts\AsStringable cast class to cast a model attribute to a fluent Illuminate\Support\Stringable object:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Casts\AsStringable;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * Get the attributes that should be cast.
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'directory' => AsStringable::class,
        ];
    }
}

Array and JSON Casting

The array cast is particularly useful when working with columns that are stored as serialized JSON. For example, if your database has a JSON or TEXT field type that contains serialized JSON, adding the array cast to that attribute will automatically deserialize the attribute to a PHP array when you access it on your Eloquent model:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * Get the attributes that should be cast.
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'options' => 'array',
        ];
    }
}

Once the cast is defined, you may access the options attribute and it will automatically be deserialized from JSON into a PHP array. When you set the value of the options attribute, the given array will automatically be serialized back into JSON for storage:

use App\Models\User;

$user = User::find(1);

$options = $user->options;

$options['key'] = 'value';

$user->options = $options;

$user->save();

To update a single field of a JSON attribute with a more terse syntax, you may make the attribute mass assignable and use the -> operator when calling the update method:

$user = User::find(1);

$user->update(['options->key' => 'value']);

JSON and Unicode

If you would like to store an array attribute as JSON with unescaped Unicode characters, you may use the json:unicode cast:

/**
 * Get the attributes that should be cast.
 *
 * @return array<string, string>
 */
protected function casts(): array
{
    return [
        'options' => 'json:unicode',
    ];
}

Array Object and Collection Casting

Although the standard array cast is sufficient for many applications, it does have some disadvantages. Since the array cast returns a primitive type, it is not possible to mutate an offset of the array directly. For example, the following code will trigger a PHP error:

$user = User::find(1);

$user->options['key'] = $value;

To solve this, Laravel offers an AsArrayObject cast that casts your JSON attribute to an ArrayObject class. This feature is implemented using Laravel's custom cast implementation, which allows Laravel to intelligently cache and transform the mutated object such that individual offsets may be modified without triggering a PHP error. To use the AsArrayObject cast, simply assign it to an attribute:

use Illuminate\Database\Eloquent\Casts\AsArrayObject;

/**
 * Get the attributes that should be cast.
 *
 * @return array<string, string>
 */
protected function casts(): array
{
    return [
        'options' => AsArrayObject::class,
    ];
}

Similarly, Laravel offers an AsCollection cast that casts your JSON attribute to a Laravel Collection instance:

use Illuminate\Database\Eloquent\Casts\AsCollection;

/**
 * Get the attributes that should be cast.
 *
 * @return array<string, string>
 */
protected function casts(): array
{
    return [
        'options' => AsCollection::class,
    ];
}

If you would like the AsCollection cast to instantiate a custom collection class instead of Laravel's base collection class, you may provide the collection class name as a cast argument:

use App\Collections\OptionCollection;
use Illuminate\Database\Eloquent\Casts\AsCollection;

/**
 * Get the attributes that should be cast.
 *
 * @return array<string, string>
 */
protected function casts(): array
{
    return [
        'options' => AsCollection::using(OptionCollection::class),
    ];
}

The of method may be used to indicate collection items should be mapped into a given class via the collection's mapInto method:

use App\ValueObjects\Option;
use Illuminate\Database\Eloquent\Casts\AsCollection;

/**
 * Get the attributes that should be cast.
 *
 * @return array<string, string>
 */
protected function casts(): array
{
    return [
        'options' => AsCollection::of(Option::class)
    ];
}

When mapping collections to objects, the object should implement the Illuminate\Contracts\Support\Arrayable and JsonSerializable interfaces to define how their instances should be serialized into the database as JSON:

<?php

namespace App\ValueObjects;

use Illuminate\Contracts\Support\Arrayable;
use JsonSerializable;

class Option implements Arrayable, JsonSerializable
{
    public string $name;
    public mixed $value;
    public bool $isLocked;

    /**
     * Create a new Option instance.
     */
    public function __construct(array $data)
    {
        $this->name = $data['name'];
        $this->value = $data['value'];
        $this->isLocked = $data['is_locked'];
    }

    /**
     * Get the instance as an array.
     *
     * @return array{name: string, data: string, is_locked: bool}
     */
    public function toArray(): array
    {
        return [
            'name' => $this->name,
            'value' => $this->value,
            'is_locked' => $this->isLocked,
        ];
    }

    /**
     * Specify the data which should be serialized to JSON.
     *
     * @return array{name: string, data: string, is_locked: bool}
     */
    public function jsonSerialize(): array
    {
        return $this->toArray();
    }
}

Date Casting

By default, Eloquent will cast the created_at and updated_at columns to instances of Carbon, which extends the PHP DateTime class and provides an assortment of helpful methods. You may cast additional date attributes by defining additional date casts within your model's casts method. Typically, dates should be cast using the datetime or immutable_datetime cast types.

When defining a date or datetime cast, you may also specify the date's format. This format will be used when the model is serialized to an array or JSON:

/**
 * Get the attributes that should be cast.
 *
 * @return array<string, string>
 */
protected function casts(): array
{
    return [
        'created_at' => 'datetime:Y-m-d',
    ];
}

When a column is cast as a date, you may set the corresponding model attribute value to a UNIX timestamp, date string (Y-m-d), date-time string, or a DateTime / Carbon instance. The date's value will be correctly converted and stored in your database.

You may customize the default serialization format for all of your model's dates by defining a serializeDate method on your model. This method does not affect how your dates are formatted for storage in the database:

/**
 * Prepare a date for array / JSON serialization.
 */
protected function serializeDate(DateTimeInterface $date): string
{
    return $date->format('Y-m-d');
}

To specify the format that should be used when actually storing a model's dates within your database, you should define a $dateFormat property on your model:

/**
 * The storage format of the model's date columns.
 *
 * @var string
 */
protected $dateFormat = 'U';

Date Casting, Serialization, and Timezones

By default, the date and datetime casts will serialize dates to a UTC ISO-8601 date string (YYYY-MM-DDTHH:MM:SS.uuuuuuZ), regardless of the timezone specified in your application's timezone configuration option. You are strongly encouraged to always use this serialization format, as well as to store your application's dates in the UTC timezone by not changing your application's timezone configuration option from its default UTC value. Consistently using the UTC timezone throughout your application will provide the maximum level of interoperability with other date manipulation libraries written in PHP and JavaScript.

If a custom format is applied to the date or datetime cast, such as datetime:Y-m-d H:i:s, the inner timezone of the Carbon instance will be used during date serialization. Typically, this will be the timezone specified in your application's timezone configuration option. However, it's important to note that timestamp columns such as created_at and updated_at are exempt from this behavior and are always formatted in UTC, regardless of the application's timezone setting.

Enum Casting

Eloquent also allows you to cast your attribute values to PHP Enums. To accomplish this, you may specify the attribute and enum you wish to cast in your model's casts method:

use App\Enums\ServerStatus;

/**
 * Get the attributes that should be cast.
 *
 * @return array<string, string>
 */
protected function casts(): array
{
    return [
        'status' => ServerStatus::class,
    ];
}

Once you have defined the cast on your model, the specified attribute will be automatically cast to and from an enum when you interact with the attribute:

if ($server->status == ServerStatus::Provisioned) {
    $server->status = ServerStatus::Ready;

    $server->save();
}

Casting Arrays of Enums

Sometimes you may need your model to store an array of enum values within a single column. To accomplish this, you may utilize the AsEnumArrayObject or AsEnumCollection casts provided by Laravel:

use App\Enums\ServerStatus;
use Illuminate\Database\Eloquent\Casts\AsEnumCollection;

/**
 * Get the attributes that should be cast.
 *
 * @return array<string, string>
 */
protected function casts(): array
{
    return [
        'statuses' => AsEnumCollection::of(ServerStatus::class),
    ];
}

Encrypted Casting

The encrypted cast will encrypt a model's attribute value using Laravel's built-in encryption features. In addition, the encrypted:array, encrypted:collection, encrypted:object, AsEncryptedArrayObject, and AsEncryptedCollection casts work like their unencrypted counterparts; however, as you might expect, the underlying value is encrypted when stored in your database.

As the final length of the encrypted text is not predictable and is longer than its plain text counterpart, make sure the associated database column is of TEXT type or larger. In addition, since the values are encrypted in the database, you will not be able to query or search encrypted attribute values.

Key Rotation

As you may know, Laravel encrypts strings using the key configuration value specified in your application's app configuration file. Typically, this value corresponds to the value of the APP_KEY environment variable. If you need to rotate your application's encryption key, you will need to manually re-encrypt your encrypted attributes using the new key.

Query Time Casting

Sometimes you may need to apply casts while executing a query, such as when selecting a raw value from a table. For example, consider the following query:

use App\Models\Post;
use App\Models\User;

$users = User::select([
    'users.*',
    'last_posted_at' => Post::selectRaw('MAX(created_at)')
        ->whereColumn('user_id', 'users.id')
])->get();

The last_posted_at attribute on the results of this query will be a simple string. It would be wonderful if we could apply a datetime cast to this attribute when executing the query. Thankfully, we may accomplish this using the withCasts method:

$users = User::select([
    'users.*',
    'last_posted_at' => Post::selectRaw('MAX(created_at)')
        ->whereColumn('user_id', 'users.id')
])->withCasts([
    'last_posted_at' => 'datetime'
])->get();

自定义类型转换

Laravel 有许多内置的很有用的转换类型;然而,你有时可能需要定义自己的转换类型。要创建一个类型转换,请执行 make:cast Artisan 命令。新的转换类将放置在你的 app/Casts 目录中:

php artisan make:cast AsJson

所有自定义转换类都实现了 CastsAttributes 接口。实现此接口的类必须定义一个 getset 方法。get 方法负责将数据库中的原始值变换为转换值,而 set 方法应该将转换值变换为可以存储在数据库中的原始值。作为一个例子,我们将内置的 json 转换类型重新实现为一个自定义转换类型:

<?php

namespace App\Casts;

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use Illuminate\Database\Eloquent\Model;

class AsJson implements CastsAttributes
{
    /**
     * 转换给定的值。
     *
     * @param  array<string, mixed>  $attributes
     * @return array<string, mixed>
     */
    public function get(
        Model $model,
        string $key,
        mixed $value,
        array $attributes,
    ): array {
        return json_decode($value, true);
    }

    /**
     * 为存储准备给定的值。
     *
     * @param  array<string, mixed>  $attributes
     */
    public function set(
        Model $model,
        string $key,
        mixed $value,
        array $attributes,
    ): string {
        return json_encode($value);
    }
}

一旦明确好一个自定义转换类型,你就可以使用其类名将其附加到模型属性上:

<?php

namespace App\Models;

use App\Casts\AsJson;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * 获取应类型转换的属性。
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'options' => AsJson::class,
        ];
    }
}
dkp 翻译于 1周前

值对象类型转换

不限于将值转换为原始类型,你还可以将值转换为对象。定义将值转换为对象的自定义转换与转换为原始类型非常相似;但是,set 方法应返回一个键 / 值对数组,这些键 / 值对将用于在模型上设置原始的可存储值。

作为一个例子,我们将定义一个自定义转换类,该类将多个模型值转换为一个 Address 值对象。我们假设 Address 值对象有两个公共属性:lineOnelineTwo

<?php

namespace App\Casts;

use App\ValueObjects\Address;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use Illuminate\Database\Eloquent\Model;
use InvalidArgumentException;

class AsAddress implements CastsAttributes
{
    /**
     * 转换给定的值。
     *
     * @param  array<string, mixed>  $attributes
     */
    public function get(
        Model $model,
        string $key,
        mixed $value,
        array $attributes,
    ): Address {
        return new Address(
            $attributes['address_line_one'],
            $attributes['address_line_two']
        );
    }

    /**
     * 存储准备给定的值。
     *
     * @param  array<string, mixed>  $attributes
     * @return array<string, string>
     */
    public function set(
        Model $model,
        string $key,
        mixed $value,
        array $attributes,
    ): array {
        if (! $value instanceof Address) {
            throw new InvalidArgumentException('The given value is not an Address instance.');
        }

        return [
            'address_line_one' => $value->lineOne,
            'address_line_two' => $value->lineTwo,
        ];
    }
}

在类型转换为值对象时,对值对象所做的任何更改都会在模型保存之前自动同步回模型:

use App\Models\User;

$user = User::find(1);

$user->address->lineOne = 'Updated Address Value';

$user->save();

[! 注意]
如果你打算将包含值对象的 Eloquent 模型序列化为 JSON 或数组,你应该在值对象上实现 Illuminate\Contracts\Support\ArrayableJsonSerializable 接口。

dkp 翻译于 1周前

值对象缓存

解析转换为值对象的属性时,它们会被 Eloquent 缓存。因此,如果再次访问该属性,将返回相同的对象实例。

如果你想禁用自定义类型转换类的对象缓存行为,可以在自定义转换类上声明一个公共的 withoutObjectCaching 属性:

class AsAddress implements CastsAttributes
{
    public bool $withoutObjectCaching = true;

    // ...
}

数组 / JSON 序列化

当使用 toArraytoJson 方法将 Eloquent 模型转换为数组或 JSON 时,只要你的自定义转换值对象有实现 Illuminate\Contracts\Support\ArrayableJsonSerializable 接口,它们通常也会被序列化。可是,当使用第三方库提供的值对象时,你可能没有能力向对象添加这些接口。

因此,你可以指定你的自定义转换类用于负责序列化值对象。为此,你的自定义转换类应该实现 Illuminate\Contracts\Database\Eloquent\SerializesCastableAttributes 接口。该接口表明你的类应该包含一个 serialize 方法,该方法应返回值对象的序列化形式:

/**
 * 获取值的序列化表示形式。
 *
 * @param  array<string, mixed>  $attributes
 */
public function serialize(
    Model $model,
    string $key,
    mixed $value,
    array $attributes,
): string {
    return (string) $value;
}

入站类型转换

有时,你可能需要编写一个自定义转换类,该类仅转换正在设置到模型上的值,并且在从模型检索属性时不执行任何操作。

dkp 翻译于 1周前

仅入站的自定义转换应实现 CastsInboundAttributes 接口,该接口仅需要定义一个 set 方法。调用带 --inbound 选项的 make:cast Artisan 命令来生成仅入站的转换类:

php artisan make:cast AsHash --inbound

仅入站转换的一个经典例子是「哈希」转换。例如,我们可以定义一个通过给定算法对入站值进行哈希处理的转换:

<?php

namespace App\Casts;

use Illuminate\Contracts\Database\Eloquent\CastsInboundAttributes;
use Illuminate\Database\Eloquent\Model;

class AsHash implements CastsInboundAttributes
{
    /**
     * 创建一个新的类型转换类实例。
     */
    public function __construct(
        protected string|null $algorithm = null,
    ) {}

    /**
     * 为存储准备给定的值。
     *
     * @param  array<string, mixed>  $attributes
     */
    public function set(
        Model $model,
        string $key,
        mixed $value,
        array $attributes,
    ): string {
        return is_null($this->algorithm)
            ? bcrypt($value)
            : hash($this->algorithm, $value);
    }
}

类型转换参数

当将自定义转换附加到模型时,可以通过使用 : 字符分隔类名称并将多个参数用逗号分隔来指定转换参数。参数将被传递给转换类的构造函数:

/**
 * 获取应类型转换的属性。
 *
 * @return array<string, string>
 */
protected function casts(): array
{
    return [
        'secret' => AsHash::class.':sha256',
    ];
}

可转换类

你可能想要允许应用程序的值对象定义它们自己的自定义转换类。你不需要将自定义转换类附加到模型上,而是可以附加一个实现了 Illuminate\Contracts\Database\Eloquent\Castable 接口的值对象类:

use App\ValueObjects\Address;

protected function casts(): array
{
    return [
        'address' => Address::class,
    ];
}
dkp 翻译于 1周前

实现 Castable 接口的对象必须定义一个 castUsing 方法,该方法返回负责从 Castable 类转换的自定义转换类类名:

<?php

namespace App\ValueObjects;

use Illuminate\Contracts\Database\Eloquent\Castable;
use App\Casts\AsAddress;

class Address implements Castable
{
    /**
     * 获取在从/向此转换目标转换时要使用的转换类名称。
     *
     * @param  array<string, mixed>  $arguments
     */
    public static function castUsing(array $arguments): string
    {
        return AsAddress::class;
    }
}

当使用 Castable 类时,你仍然可以在 casts 方法定义中提供参数。参数将被传递给 castUsing 方法:

use App\ValueObjects\Address;

protected function casts(): array
{
    return [
        'address' => Address::class.':argument',
    ];
}

可转换类和匿名转换类

通过将「可转换类」与 PHP 的匿名类结合,你可以将值对象及其转换逻辑定义为一个单一的可转换对象。为此,从值对象的 castUsing 方法返回一个匿名类。匿名类应实现 CastsAttributes 接口:

<?php

namespace App\ValueObjects;

use Illuminate\Contracts\Database\Eloquent\Castable;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;

class Address implements Castable
{
    // ...

    /**
     * 获取在从/向此转换目标转换时要使用的转换类。
     *
     * @param  array<string, mixed>  $arguments
     */
    public static function castUsing(array $arguments): CastsAttributes
    {
        return new class implements CastsAttributes
        {
            public function get(
                Model $model,
                string $key,
                mixed $value,
                array $attributes,
            ): Address {
                return new Address(
                    $attributes['address_line_one'],
                    $attributes['address_line_two']
                );
            }

            public function set(
                Model $model,
                string $key,
                mixed $value,
                array $attributes,
            ): array {
                return [
                    'address_line_one' => $value->lineOne,
                    'address_line_two' => $value->lineTwo,
                ];
            }
        };
    }
}
dkp 翻译于 1周前

本文章首发在 LearnKu.com 网站上。

本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
贡献者:1
讨论数量: 2
发起讨论 只看当前版本


覺者
laravel6.X 模型 定义修改器问题
0 个点赞 | 9 个回复 | 代码速记 | 课程版本 6.x
UpGod
laravel9 定义修改器失败!
0 个点赞 | 6 个回复 | 问答 | 课程版本 9.x