PHP 基本功足够扎实的情况下,强烈建议学习 Laravel 的过程除了阅读官方文档外,仔细阅读框架源码;或许会有小惊喜哟。
0x00 准备
- Laravel 5.6
php artisan make:migration ...
近期在项目过程中,遇到这么个需求:在所有模型表内都需要支持自增主键 id
、创建时间、更新时间以及软删除,以备不时之需。
于是乎。传统的做法是,在每个迁移 Schema::create
回调内,都写一遍 $table->increments
+ softDeletes
+ timestamps
,就像这样:
Schema::create('foo', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->softDeletes();
});
随着表越来越多,重复代码也越来越多,对于我这个强迫症来说简直看着相当不爽😂;而且一旦需要修改就很坑,Git 提交记录也会很杂乱又低价值。
0x01 思路
最开始想到的方案是,继承 Schema Facade,重写 create
调用统一的回调函数加入这三个字段;但是这种方法具有侵入性,也就是说所有的表都必须带这三个字段,后期个别表如果有特殊需求就比较麻烦了。
于是乎去看了下 Blueprint
的源码,发现一个神器 Macroable
trait,2333。
0x02 解决
首先定义一个服务提供者,并修改 config/app.php
的 providers
内增加此服务提供者。
php artisan make:provider BlueprintMacroProvider
// config/app.php
'providers' => [
// ...
/*
* Application Service Providers...
*/
App\Providers\BlueprintMacroProvider::class,
]
在此提供者的 register
方法内,创建 Macro
即可。
// ...
public function register()
{
Blueprint::macro('myColumns', function() {
$table->increments('id');
$table->timestamps();
$table->softDeletes();
});
}
在所有创建表的回调函数内,调用此 Macro
即可。于是上面的三行代码就变成了一行:
Schema::create('foo', function (Blueprint $table) {
$table->myColumns(); // 方法名就是我们定义 macro 时使用的第一个参数。
});
搞定,统一到 myColumns
里处理。
0x03 拓展
有兴趣可以看下 https://laravel.com/docs/5.6/responses#response-macros,这里有 Laravel HTTP Response 对于其 Macro 的介绍。实际上,Laravel 的响应也是同样使用 Macroable
trait 实现的此功能。