sfneal / laravel-custom-casts
Requires
- php: ^8.0
Requires (Dev)
- orchestra/testbench: ^7.40|^8.0|9.0
- phpunit/phpunit: ^9.6|^10.0|^11.0
This package is auto-updated.
Last update: 2024-07-16 17:39:50 UTC
README
为 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' ]; }
除了 boolean
、integer
和 decimal
之外,Laravel 本身支持 real
、float
、double
、string
、object
、array
、collection
、date
、datetime
和 timestamp
转换。
有时使用自定义逻辑处理更复杂的类型很方便,并且需要转换能够监听并响应模型事件。这正是此软件包派上用场的地方。
如果使用自定义转换存储图像,并在模型删除时需要删除它,直接从自定义转换处理事件可能非常有用。请参阅 旧文档 了解此示例。
📦 vkovic 软件包 📦
请查看我的其他软件包——它们都是免费的、编写良好的,其中一些很有用 😄。如果您发现某些有趣的内容,请考虑在软件包开发中帮助我,提出想法或某种改进建议,如果您喜欢,请为仓库点赞,或者简单地查看代码 - 底下有很多有用的东西。
- vkovic/laravel-commando ~ 有用的
artisan
命令集合 - 即将推出 vkovic/laravel-event-log ~ 简单地记录和访问记录的事件,可选地带有附加数据和相关的模型
兼容性
该软件包与 Laravel 版本 5.5
、5.6
、5.7
、5.8
和 6
兼容
以及 Lumen 版本 5.5
、5.6
、5.7
、5.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
方法外,我们还可以为标准模型事件定义其他方法:retrieved
、creating
、created
、updating
、saving
、saved
、deleting
、deleted
、restoring
和restored
。
其他功能
如上所示,我们可以轻松访问转换后的属性名称以及底层模型的实例。
// 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包,应运行其附带的所有测试。使用Docker
、docker-compose
和phpunit
是最简单的方法之一。
首先,我们需要初始化Docker容器(有关详细信息,请参阅docker-composer.yaml
)。
docker-compose up --exit-code-from app
然后,我们可以运行测试并查看输出
docker-compose run --rm app phpunit