在之前,開發者須要爲每個須要調度的任務編寫一個Cron條目,這是很讓人頭疼的事。你的任務調度不在源碼控制中,你必須使用SSH登陸到服務器而後添加這些Cron條目。Laravel命令調度器容許你平滑而又富有表現力地在Laravel中定義命令調度,而且服務器上只須要一個Cron條目便可。php
任務調度定義在app/Console/Kernel.php
文件的schedule
方法中,該方法中已經包含了一個示例。你能夠自由地添加你須要的調度任務到Schedule
對象。node
下面是你惟一須要添加到服務器的Cron條目:數據庫
php /path/to/artisan schedule:run 1>> /dev/null 2>&1
你能夠在
App\Console\Kernel
類的schedule
方法中定義全部調度任務。開始以前,讓咱們看一個調度任務的例子,在這個例子中,咱們將會在天天午夜調度一個被調用的閉包。在這個閉包中咱們將會執行一個數據庫查詢來清空表:json
<?php namespace App\Console; use DB; use Illuminate\Console\Scheduling\Schedule; use Illuminate\Foundation\Console\Kernel as ConsoleKernel; class Kernel extends ConsoleKernel{ /** * 應用提供的Artisan命令 * * @var array */ protected $commands = [ 'App\Console\Commands\Inspire', ]; /** * 定義應用的命令調度 * * @param \Illuminate\Console\Scheduling\Schedule $schedule * @return void */ protected function schedule(Schedule $schedule) { $schedule->call(function () { DB::table('recent_users')->delete(); })->daily(); } }
除了調度閉包調用外,還能夠調度Artisan命令
和操做系統命令。例如,可使用command
方法來調度一個Artisan
命令:服務器
$schedule->command('emails:send --force')->daily();
exec
命令可用於發送命令到操做系統:閉包
$schedule->exec('node /home/forge/script.js')->daily();
固然,你能夠分配多種調度到任務:app
方法 | 描述 |
---|---|
->cron(' * '); | 在自定義Cron調度上運行任務 |
->everyMinute(); | 每分鐘運行一次任務 |
->everyFiveMinutes(); | 每五分鐘運行一次任務 |
->everyTenMinutes(); | 每十分鐘運行一次任務 |
->everyThirtyMinutes(); | 每三十分鐘運行一次任務 |
->hourly(); | 每小時運行一次任務 |
->daily(); | 天天凌晨零點運行任務 |
->dailyAt('9:00'); | 天天9:00運行任務 |
->twiceDaily(1, 9); | 天天1:00 & 9:00運行任務 |
->weekly(); | 每週運行一次任務 |
->monthly(); | 每個月運行一次任務 |
這些方法能夠和額外的約束一塊兒聯合起來建立一週特定時間運行的更加細粒度的調度,例如,要每週一調度一個命令:composer
$schedule->call(function () { // 每週星期一9:00運行一次... })->weekly()->mondays()->at('9:00');
下面是額外的調度約束列表:測試
方法 | 描述 |
---|---|
->weekdays(); | 只在工做日運行任務 |
->sundays(); | 每一個星期天運行任務 |
->mondays(); | 每一個星期一運行任務 |
->tuesdays(); | 每一個星期二運行任務 |
->wednesdays(); | 每一個星期三運行任務 |
->thursdays(); | 每一個星期四運行任務 |
->fridays(); | 每一個星期五運行任務 |
->saturdays(); | 每一個星期六運行任務 |
->when(Closure); | 基於特定測試運行任務 |
when
方法用於限制任務在經過給定測試以後運行。換句話說,若是給定閉包返回true
,只要沒有其它約束條件阻止任務運行,該任務就會執行:url
$schedule->command('emails:send')->daily()->when(function () { return true; });
默認狀況下,即便前一個任務仍然在運行調度任務也會運行,要避免這樣的狀況,可以使用withoutOverlapping
方法:
$schedule->command('emails:send')->withoutOverlapping();
在本例中,Artisan命令
emails:send
每分鐘都會運行,若是該命令沒有在運行的話。若是你的任務在執行時常常大幅度的變化,那麼withoutOverlapping
方法就很是有用,你沒必要再去預測給定任務到底要消耗多長時間。
Laravel調度器爲處理調度任務輸出提供了多個方便的方法。首先,使用sendOutputTo
方法,你能夠發送輸出到文件以便稍後檢查:
$schedule->command('emails:send') ->daily() ->sendOutputTo($filePath);
使用emailOutputTo
方法,你能夠將輸出發送到電子郵件,注意輸出必須首先經過sendOutputTo
方法發送到文件。還有,使用電子郵件發送任務輸出以前,應該配置Laravel的電子郵件服務
:
$schedule->command('foo') ->daily() ->sendOutputTo($filePath) ->emailOutputTo('foo@example.com');
注意:emailOutputTo和sendOutputTo方法只對command方法有效,不支持call方法。
使用before
和after
方法,你能夠指定在調度任務完成以前和以後要執行的代碼:
$schedule->command('emails:send') ->daily() ->before(function () { // Task is about to start... }) ->after(function () { // Task is complete... });
使用
pingBefore
和thenPing
方法,調度器能夠在任務完成以前和以後自動ping給定的URL。該方法在通知外部服務時頗有用,例如Laravel Envoyer
,在調度任務開始或完成的時候:
$schedule->command('emails:send') ->daily() ->pingBefore($url) ->thenPing($url);
使用pingBefore($url)
或thenPing($url)
特性須要安裝HTTP庫Guzzle
,能夠在composer.json
文件中添加以下行來安裝Guzzle到項目:
"guzzlehttp/guzzle": "~5.3|~6.0"