sfneal/laravel-custom-casts

该软件包已被放弃,不再维护。作者建议使用 vkovic/laravel-custom-casts 软件包。

为 Laravel 模型属性创建自己的自定义转换类型

v1.5.0 2024-04-16 02:05 UTC

README

Build Downloads Stable License

为 Laravel 模型属性创建自己的转换类型

Laravel 自定义转换与 Eloquent 属性转换类似,但具有自定义逻辑(在单独的类中)。这意味着我们可以在多个模型中使用相同的转换逻辑 - 我们可能写 图片上传逻辑 并在各个地方使用它。除了转换到自定义类型,此软件包还允许自定义转换监听并响应底层模型事件。

让我们回顾一些 Laravel 常见的转换类型及其使用示例

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    protected $casts = [
        'is_admin' => 'boolean',
        'login_count' => 'integer'
        'height' => 'decimal:2'
    ];
}

除了 booleanintegerdecimal 之外,Laravel 本身支持 realfloatdoublestringobjectarraycollectiondatedatetimetimestamp 转换。

有时使用自定义逻辑处理更复杂的类型很方便,并且需要转换能够监听并响应模型事件。这正是此软件包派上用场的地方。

如果使用自定义转换存储图像,并在模型删除时需要删除它,直接从自定义转换处理事件可能非常有用。请参阅 旧文档 了解此示例。

📦 vkovic 软件包 📦

请查看我的其他软件包——它们都是免费的、编写良好的,其中一些很有用 😄。如果您发现某些有趣的内容,请考虑在软件包开发中帮助我,提出想法或某种改进建议,如果您喜欢,请为仓库点赞,或者简单地查看代码 - 底下有很多有用的东西。

兼容性

该软件包与 Laravel 版本 5.55.65.75.86 兼容

以及 Lumen 版本 5.55.65.75.8

Laravel 7+ 对 自定义转换 有原生的支持,与此库不兼容。

PHP 的最低支持版本为 7.1。PHP 8 也受支持。

安装

通过 Composer 安装软件包

composer require vkovic/laravel-custom-casts

使用方法

使用自定义转换类

要在模型中启用自定义转换,请使用 HasCustomCasts 特性,并使用 $casts 定义哪些属性将被转换——按照 Laravel 标准。

// File: app/User.php

namespace App;

use App\CustomCasts\NameCast;
use Illuminate\Database\Eloquent\Model;
use Vkovic\LaravelCustomCasts\HasCustomCasts;

class User extends Model
{
    use HasCustomCasts;

    protected $casts = [
        'is_admin' => 'boolean', // <-- Laravel default cast type
        'name' => NameCast::class // <-- Our custom cast class (see the section below)
    ];
}

定义自定义转换类

此类将负责我们的自定义转换逻辑。

// File: app/CustomCasts/NameCast.php

namespace App\CustomCasts;

use Vkovic\LaravelCustomCasts\CustomCastBase;

class NameCast extends CustomCastBase
{
    public function setAttribute($value)
    {
        return ucwords($value);
    }

    public function castAttribute($value)
    {
        return $this->getTitle() . ' ' . $value;
    }

    protected function getTitle()
    {
        return ['Mr.', 'Mrs.', 'Ms.', 'Miss'][rand(0, 3)];
    }
}

必需的 setAttribute 方法接收要设置在模型字段上的 $value,应返回要存储在数据库中的原始值。

可选的castAttribute方法接收来自数据库的原始$value,并应返回一个变异值。如果省略此方法,将返回原始数据库值。

为了这个例子,我们将实现一个额外的方法,当从数据库中检索用户名称时,将为用户附加一个随机标题。

测试自定义转换类

让我们创建一个用户并看看会发生什么。

$user = new App\User;
$user->name = 'john doe';

$user->save();

这将创建我们的新用户并将他们的名字存储在数据库中,每个单词的首字母大写。

当我们检索用户并尝试访问他们的名字时,标题将被添加到它的前面——就像我们在自定义NameCast类中定义的那样。

dd($user->name); // 'Mr. John Doe'

处理模型事件

假设我们想在用户的名字发生变化时通知管理员。

// File: app/CustomCasts/NameCast.php

public function updated()
{
    $attribute = $this->attribute;

    if($this->model->isDirty($attribute)) {
        // Notify admin about name change
    }
}

除了updated方法外,我们还可以为标准模型事件定义其他方法:retrievedcreatingcreatedupdatingsavingsaveddeletingdeletedrestoringrestored

其他功能

如上所示,我们可以轻松访问转换后的属性名称以及底层模型的实例。

// File: app/CustomCasts/NameCast.php

// Get the name of the model attribute being casted
dd($this->attribute); // 'name'

// Access our `User` model
dd(get_class($this->model)); // 'App/User'

我们还可以直接从模型中检索所有转换后的属性及其相应的类。

// File: app/User.php

dd($this->getCustomCasts()); // ['name' => 'App/CustomCasts/NameCast']

使用别名转换

您可能会发现使用别名进行自定义转换更简单,例如。

protected $casts = [
    'avatar' => 'image' // <-- You prefer this ...
    // ---
    'avatar' => ImageCast::class // <-- ... over this
];

为了实现魔法,首先将包的service provider添加到providers数组中

// File: config/app.php

'providers' => [
    // ...

    /*
     * Package Service Providers...
     */
    Vkovic\LaravelCustomCasts\CustomCastsServiceProvider::class

    // ...
]

添加提供者后,发布配置文件,该文件将用于将别名与其对应的自定义转换类关联起来

php artisan vendor:publish --provider="Vkovic\LaravelCustomCasts\CustomCastsServiceProvider"

此命令应在config/custom_casts.php位置创建一个配置文件。打开它并查看配置选项的示例注释。

在不使用Laravel的情况下使用

此包也可以在不安装完整Laravel的情况下使用,例如使用jenssegers/model或如果您的项目使用illuminate/database库。

更多示例

您可以在旧文档中找到更多示例。

贡献

如果您计划修改此Laravel包,应运行其附带的所有测试。使用Dockerdocker-composephpunit是最简单的方法之一。

首先,我们需要初始化Docker容器(有关详细信息,请参阅docker-composer.yaml)。

docker-compose up --exit-code-from app

然后,我们可以运行测试并查看输出

docker-compose run --rm app phpunit