簡介
之前我們已經學習了 Events 和 Listeners ,這次我們來學習 Jobs。
Jobs的建立
運行命令列 php artisan make:job CompileReports 建立一個Job類,Job類的結構簡單,一般來說只會包含一個讓隊列用來調用此任務的 handle 方法,具體代碼如下:
class CompileReports extends Job implements SelfHandling{ /** * Create a new job instance. * * @return void */ public function __construct() { // } /** * Execute the job. * * @return void */ public function handle() { // }}
可以通過 php artisan help make:job 觀察相關參數,執行 php artisan make:job CompileReports --queued ,對比發現和之前類區別為多實現了 ShouldQueue 介面,這意味著可以按隊列順序執行。
增加路由和控制器
預設路由 routes.php 中增加:
Route::get('reports', 'ReportsController@index');
通過執行命令列 php artisan make:controller ReportsController --plain ,建立 ReportsController 控制器,增加測試方法:
class ReportsController extends Controller{ // public function index() { $job = new CompileReports(); $this->dispatch($job); return 'Done'; } }
ReportsController 控制器的 Controller 父類中,預設已經 use DispatchesJobs ,定義好了 dispatch($job) 方法,用來調度任務。這時我們訪問頁面效果如:
Job中參數處理
改寫 CompileReports.php 代碼,建構函式中接受 $reportId 參數:
class CompileReportsextends Jobimplements SelfHandling, ShouldQueue{ protected $reportId; /** * Create a new job instance. * * @return void */ public function __construct($reportId) { // $this->reportId = $reportId; } /** * Execute the job. * * @return void */ public function handle() { // var_dump('Compiling the reports with the id '. $this->reportId .' within the Job class.'); }}
ReportsController 控制器中接受請求中參數,轉寄給Job處理:
class ReportsController extends Controller{ public function index(Request $request) { $job = new CompileReports($request->input('reportId')); $this->dispatch($job); return 'Done'; }}
訪問頁面效果如下:
Job中多參數處理
ReportsController 中改為調用 dispatchFrom 方法:
class ReportsController extends Controller{ // public function index(Request $request) { //$job = new CompileReports($request->input('reportId')); // $this->dispatchFrom(CompileReports::class, $request); $this->dispatchFrom('App\Jobs\CompileReports', $request); return 'Done'; } }
其中 DispatchesJobs 中定義了 dispatch 及 dispatchFrom,如下:
trait DispatchesJobs{ /** * Dispatch a job to its appropriate handler. * * @param mixed $job * @return mixed */ protected function dispatch($job) { return app('Illuminate\Contracts\Bus\Dispatcher')->dispatch($job); } /** * Marshal a job and dispatch it to its appropriate handler. * * @param mixed $job * @param array $array * @return mixed */ protected function dispatchFromArray($job, array $array) { return app('Illuminate\Contracts\Bus\Dispatcher')->dispatchFromArray($job, $array); } /** * Marshal a job and dispatch it to its appropriate handler. * 整理參數列表,傳遞給job * @param mixed $job * @param \ArrayAccess $source * @param array $extras * @return mixed */ protected function dispatchFrom($job, ArrayAccess $source, $extras = []) { return app('Illuminate\Contracts\Bus\Dispatcher')->dispatchFrom($job, $source, $extras); }}
CompileReports 類中改寫傳入參數:
class CompileReportsextends Jobimplements SelfHandling, ShouldQueue{ protected $reportId; protected $type; /** * Create a new job instance. * * @return void */ public function __construct($reportId, $type) { // $this->reportId = $reportId; $this->type = $type; } /** * Execute the job. * * @return void */ public function handle() { // var_dump('Compiling the '. $this->type .' reports with the id '. $this->reportId .' within the Job class.'); }}
訪問效果如:
在 Job 中添加 DispatchesJobs 引用後,可繼續指派Job:
/*** Execute the job.** @return void*/public function handle(){ // var_dump('Compiling the '. $this->type .' reports with the id '. $this->reportId .' within the Job class.'); var_dump(sprintf('Compiling the %s report with the id %s within the Job class', $this->type, $this->reportId)); // 增加 DispatchesJobs 引用後,可繼續指派 job if(true) { $this->dispatch(new DoSomethingElse); }}
訪問效果如: