Laravel 5.1 タスクスケジュール

イントロダクション

コンソールコマンドを一つ一つスケジュールするため、今まで開発者はCronエントリーを毎回作成してきました。しかしこれは悩みの種でした。コンソールの実行スケジュールはソース管理されていませんでしたし、Cronのエントリを追加するためにその都度SSHでサーバーに接続する必要がありました。人生をより簡単に生きましょう。Laravelコマンドスケジューラーを使い、サーバーにCronエントリーを一つ追加するだけで、他に何も用意しなくてもLaravelだけでコマンド実行スケジュールをスラスラと記述的に定義することができます。

コマンドスケジュールはapp/Console/Kernel.phpファイルに記述します。このクラスの中にscheduleメソッドが見つかるでしょう。始めやすいように、このメソッドの中に簡単な例を準備してあります。好きなだけジョブスケジュールをScheduleオブジェクトに追加してください。

スケジューラーを使いはじめる

唯一以下のCronエントリーだけ、サーバーに追加してください。

* * * * * php /path/to/artisan schedule:run >> /dev/null 2>&1

このCronエントリは、Laravelコマンドスケジューラーを毎分呼び出します。それにより、Laravelはスケジュールされているジョブを評価し、実行する必要のあるジョブを起動します。これ以上簡単にできません!

スケジュール定義

スケジュールタスクは全部App\Console\Kernelクラスのscheduleメソッドの中に定義します。手始めに、スケジュールタスクの例を見てください。この例は毎日深夜12時に「クロージャー」をスケジュールしています。「クロージャー」の中でテーブルをクリアするデータベースクエリーを実行しています。

<?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::class,
    ];

    /**
     * アプリケーションのコマンド実行スケジュール定義
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        $schedule->call(function () {
            DB::table('recent_users')->delete();
        })->daily();
    }
}

「クロージャー」の呼び出しをスケジュールするほかにArtisanコマンドとオペレーティングシステムコマンドを実行できます。例としてArtisanコマンドをスケジュールするcommandメソッドを使ってみましょう。

$schedule->command('emails:send --force')->daily();

オペレーティングシステムでコマンドを実行するためにはexecメソッドを使います。

$schedule->exec('node /home/forge/script.js')->daily();

繰り返しのスケジュールオプション

もちろん、タスクは様々なスケジュールを割り付けることができます。

メソッド 説明
->cron('* * * * * *'); CRON記法によるスケジュール
->everyMinute(); 毎分タスク実行
->everyFiveMinutes(); 5分毎にタスク実行
->everyTenMinutes(); 10分毎にタスク実行
->everyThirtyMinutes(); 30分毎にタスク実行
->hourly(); 毎時タスク実行
->daily(); 毎日深夜12時に実行
->dailyAt('13:00'); 毎日13:00に実行
->twiceDaily(1, 13); 毎日1:00と13:00時に実行
->weekly(); 毎週実行
->monthly(); 毎月実行
->yearly(); 毎年実行

これらのメソッドは週の特定の曜日だけに実行させるために、追加の制約と組み合わせ細かく調整できます。

$schedule->call(function () {
    // 週に一回、月曜の13:00に実行…
})->weekly()->mondays()->at('13:00');

以下が追加のスケジュール制約のリストです。

メソッド 説明
->weekdays(); ウイークデーのみに限定
->sundays(); 日曜だけに限定
->mondays(); 月曜だけに限定
->tuesdays(); 火曜だけに限定
->wednesdays(); 水曜だけに限定
->thursdays(); 木曜だけに限定
->fridays(); 金曜だけに限定
->saturdays(); 土曜だけに限定
->when(Closure); クロージャの戻り値がtureの時のみに限定

真値テスト制約

whenメソッドは指定した真値テストの結果に基づき制限を実行します。言い換えれば指定した「クロージャー」がtureを返し、他の制約が実行を停止しない限りタスクを実行します。

$schedule->command('emails:send')->daily()->when(function () {
    return true;
});

whenメソッドをいくつかチェーンした場合は、全部のwhen条件がtrueを返すときのみスケジュールされたコマンドが実行されます。

タスク多重起動の防止

デフォルトでは以前の同じジョブが起動中であっても、スケジュールされたジョブは実行されます。これを防ぐには、withoutOverlappingメソッドを使用してください。

$schedule->command('emails:send')->withoutOverlapping();

この例の場合、emails:send Artisanコマンドは実行中でない限り毎分実行されます。withoutOverlappingメソッドは指定したタスクの実行時間の変動が非常に大きく、予想がつかない場合に特に便利です。

タスク出力

Laravelスケジューラーはスケジュールしたタスクが生成する出力を取り扱う便利なメソッドをたくさん用意しています。最初にsendOutputToメソッドを使い、後ほど内容を調べられるようにファイルへ出力してみましょう。

$schedule->command('emails:send')
         ->daily()
         ->sendOutputTo($filePath);

出力を指定したファイルに追加したい場合は、appendOutputToメソッドを使います。

$schedule->command('emails:send')
         ->daily()
         ->appendOutputTo($filePath);

emailOutputToメソッドを使えば、選択したメールアドレスへ出力をメールで送ることができます。最初にsendOutputToメソッドを使い、ファイルへ出力しておく必要があることに注意してください。また、タスクの出力をメールで送る前に、Laravelのメールサービスの設定を済ませておく必要もあります。

$schedule->command('foo')
         ->daily()
         ->sendOutputTo($filePath)
         ->emailOutputTo('foo@example.com');

注意: emailOutputTosendOutputToメソッドはcommandメソッド専用で、callメソッドはサポートしていません。

タスクフック

beforeafterメソッドを使えば、スケジュールされたタスクの実行前後に指定したコードを実行することができます。

$schedule->command('emails:send')
         ->daily()
         ->before(function () {
             // タスク開始前…
         })
         ->after(function () {
             // タスク終了後…
         });

URLへのPing

pingBeforethenPingメソッドを使用し、タスク実行前後にに指定したURLへ自動的にPingをることができます。これはLaravel Envoyerのような外部サービスへスケジュールされたタスクが始まる、または完了したことを知らせるのに便利です。

$schedule->command('emails:send')
         ->daily()
         ->pingBefore($url)
         ->thenPing($url);

pingBefore($url)thenPing($url)のどちらを使用するにも、Guzzle HTTPライブラリーが必要です。Guzzleはcomposer.jsonファイルに以下の行を追加してプロジェクトに追加できます。

"guzzlehttp/guzzle": "~5.3|~6.0"

ドキュメント章別ページ

ヘッダー項目移動

注目:アイコン:ページ内リンク設置(リンクがないヘッダーへの移動では、リンクがある以前のヘッダーのハッシュをURLへ付加します。

移動

クリックで即時移動します。

設定

適用ボタンクリック後に、全項目まとめて適用されます。

カラーテーマ
和文指定 Pagination
和文指定 Scaffold
Largeスクリーン表示幅
インデント
本文フォント
コードフォント
フォント適用確認

フォントの指定フィールドから、フォーカスが外れると、当ブロックの内容に反映されます。EnglishのDisplayもPreviewしてください。

フォント設定時、表示に不具合が出た場合、当サイトのクッキーを削除してください。

バックスラッシュを含むインライン\Code\Blockの例です。

以下はコードブロックの例です。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * ユーザに関連する電話レコードを取得
     */
    public function phone()
    {
        return $this->hasOne('App\Phone');
    }
}

設定を保存する前に、表示が乱れないか必ず確認してください。CSSによるフォントファミリー指定の知識がない場合は、フォントを変更しないほうが良いでしょう。

キーボード・ショートカット

オープン操作

PDC

ページ(章)移動の左オフキャンバスオープン

HA

ヘッダー移動モーダルオープン

MS

移動/設定の右オフキャンバスオープン

ヘッダー移動

T

最初のヘッダーへ移動

E

最後のヘッダーへ移動

NJ

次ヘッダー(H2〜H4)へ移動

BK

前ヘッダー(H2〜H4)へ移動

その他

?

このヘルプページ表示
閉じる