Laravel 宏指令(Macro)动态添加自定义方法到Laravel的核心组件中
Laravel 宏指令(Macro)
在Laravel中,宏指令(Macro)是一种灵活的方式,允许您动态添加自定义方法到Laravel的核心组件中,如模型、查询构建器、集合等,以便在不改变核心代码的情况下扩展框架的功能。通过宏指令,您可以向Laravel内置的类添加自定义方法,实现更高级的功能和逻辑。
福利彩蛋:没有好玩的 API 接口?上百款免费接口等你来,免费 API,免费 API 大全
模型中定义宏指令使用示例
1. 在模型中定义宏指令
您可以在模型中定义宏指令,让模型具备额外的功能。以下是一个示例,展示如何向模型添加一个自定义的宏指令:
use Illuminate\Database\Eloquent\Model; Model::macro('customMethod', function() { // 定义自定义方法逻辑 return 'This is a custom method.'; });
2. 在查询构建器中定义宏指令
您也可以在查询构建器中定义宏指令,以便在查询数据时使用自定义的方法。以下是一个示例,展示如何向查询构建器添加一个自定义的宏指令:
use Illuminate\Database\Query\Builder; Builder::macro('whereActive', function () { return $this->where('active', '=', 1); });
3. 使用宏指令
在定义宏指令后,您可以通过具体的对象来调用宏指令定义的方法。例如,在模型中调用上面定义的 customMethod 宏指令:
$user = User::find(1); echo $user->customMethod(); // 输出:This is a custom method.
或者在查询构建器中使用上面定义的 whereActive 宏指令:
$activeUsers = DB::table('users')->whereActive()->get();
使用宏指令可以方便地为Laravel项目添加自定义方法,提高代码复用性和扩展性。同时,宏指令的灵活性使您可以根据具体需求动态地为不同的类添加自定义方法,扩展框架功能,提升开发效率。
高级使用
一、前置准备:
安装 tutorigo/laravel-ide-macros
composer require tutorigo/laravel-ide-macros php artisan vendor:publish --provider="Tutorigo\LaravelMacroHelper\IdeMacrosServiceProvider" php artisan ide-helper:macros
二、开始使用
1、新建MacrosServiceProvider或根据业务扩展需求创建RouteMacrosServiceProvider等等
2、config/app.php中添加MacrosServiceProvider注册
3、在MacrosServiceProvider boot中完成宏指令编写
1、Route macro 来定义 Route 的新方法permission
通过宏指令绑定自定义方法到路由实例
路由定义时候通过宏指令自定义的方法将响应的参数存储到路由action参数下,该参数在路由缓存的时候回一并缓存
/** * 扩展路由方法 */ Route::macro('permission', function (array $value): self { $this->action['permission'] = $value; return $this; }); Route::macro('getPermission', function (): array { return $this->action['permission'] ?? []; }); /** * 路由定义 */ Route::post('report', 'ProductController@apiReport') ->permission([ 'value' => 'productPayReport', 'name' => '付费数据统计', 'label' => '付费API统计' ]); /** * 权限中间件或其他地方使用 */ $permission = request()->getPermission()
2、Route macro 来定义 Route 的新方法full
通过新增的方法可以简洁的定义两个路由
Route::macro('full',function ($prefix, $controller){ Route::delete($prefix.'/destroy-selection', $controller.'@destroySelection')->name($prefix.'destroy-selection'); Route::apiResource($prefix, $controller); }); /** * 路由定义:一次完成两个路由定义 */ Route::full('prefix','UserController')
3、扩展数据查询builder新方法
输出完整的sql语句
// 查询构造器builder // use Illuminate\Database\Query\Builder as QBuilder; QBuilder::macro('toRawSql', function () { return array_reduce($this->getBindings(), function ($sql, $binding) { return preg_replace('/\?/', is_numeric($binding) ? $binding : "'" . $binding . "'", $sql, 1); }, $this->toSql()); }); // 数据库模型builder // use Illuminate\Database\Eloquent\Builder as EBuilder; EBuilder::macro('toRawSql', function () { return ($this->getQuery()->toRawSql()); }); // 使用,输出查询语句: var_dump(SomeModel::where('id',1)->toRawSql()) // 自定义一个tld条件查询:当前主域名符合查询要求时候主动添加一个where条件 Builder::macro('whenTldMatches', function($tld, $callback) { if (Request::tldIs($tld)) { call_user_func($callback->bindTo($this)); } return $this; }); // 使用自定义方法 SomeModel::whenTldMatches('org', function () { $this->where('id', '>', 5); })->get();
3、Request 宏指令用于检测当前的 TLD(顶级域:.com,.net,.org,.etc…)
use Illuminate\Support\Facades\Request; // 定义 Request::macro('tldIs', function ($tld) { return Str::is('*.' . $tld, $this->root()); }); // 使用 Request::tldIs('com') // returns true for app.com Request::tldIs('dev') // returns false for app.com
4、Response响应宏
use Illuminate\Support\Facades\Response; // 注册成功响应宏 Response::macro('success', function ($data = [], $message = 'success') { return new JsonResponse([ 'code' => 0, 'data' => $data, 'message' => $message ], 200); }); // 调用 return response()->success($userRepository->all(), 'success');
福利彩蛋:没有好玩的 API 接口?上百款免费接口等你来,免费 API,免费 API 大全