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-macrosphp 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 大全