vkovic / laravel-custom-casts
为Laravel模型属性创建自定义转换类型
Requires
- php: ^7.1|^8.0
Requires (Dev)
- illuminate/database: ^5.5|^6.20.14|^8.20
- orchestra/database: ^3.5|^4.0|^5.0
- orchestra/testbench: ^3.5|^4.0|^6.0
- phpunit/phpunit: ^6.3|^7.0|^8.0|^9.4
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 ];
为了使魔法发生,首先将包的服务提供者添加到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