はじめに
こんにちは。webアプリにつきもののバッチ処理ですが、もちろんLaravelでもサポートされていて、crontabに書き散らすことなくバッチを設定できます。
今回はLaravelでコンソールやcronから処理を呼び出し、バッチとして実行する方法を紹介します。
環境
- PHP 7.3.3
- Laravel 5.8.21
artisanコマンド作成
以下のコマンドで、Artisanコマンドを自作します。ここで作成するコマンドは
php artisan
でCUIから実行できますし、今回のテーマであるバッチ処理でも呼び出すことができます。
1 2 | $ php artisan make:command TestBatch Console command created successfully. |
これで
app/Console/Commands
に
TestBatch.php
が作成されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | <?php namespace App\Console\Commands; use Illuminate\Console\Command; use Illuminate\Support\Facades\DB; class TestBatch extends Command { /** * The name and signature of the console command. * artisanコマンドで呼び出す時のコマンド名を定義する * @var string */ protected $signature = 'batch:test'; /** * The console command description. * artisanコマンド一覧の出力時に表示される説明文、必須ではないが設定推奨 * @var string */ protected $description = 'お試しのバッチ処理'; /** * Create a new command instance. * * @return void */ public function __construct() { parent::__construct(); } /** * Execute the console command. * 実際の処理をこのメソッド内に記述する * @return mixed */ public function handle() { DB::table($table)->where('email', '=', 'nomura@example.com')->get(); } } |
これでもうartisanコマンドから呼び出せるようになっています。確認してみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 | $ php artisan list Laravel Framework 5.8.21 (中略) Available commands: (中略) batch batch:test お試しのバッチ処理 (中略) |
このように表示されればOKです。
php artisan batch:test
をコンソールから実行することで、先ほどの
TestBatch
クラスの
handle
メソッドが呼び出されます。
artisanコマンドをバッチとして登録する
コンソールからartisanコマンドとして呼び出せるようになりました。同じ要領でartisanコマンドを必要なだけ作り、全てcrontabに登録してもよいのですが、バッチが増えるほど煩雑になり、管理しづらくなります。
Laravel内に全てのコマンドを登録し、見通しよく管理できるようにしましょう。
app/Console/Kernel.php
を編集します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | <?php namespace App\Console; use App\Console\Commands\TestBatch; use Illuminate\Console\Scheduling\Schedule; use Illuminate\Foundation\Console\Kernel as ConsoleKernel; class Kernel extends ConsoleKernel { /** * The Artisan commands provided by your application. * ここにartisanコマンドクラスを記述する * @var array */ protected $commands = [ TestBatch::class, ]; /** * Define the application's command schedule. * artisanコマンドの実行スケジュールを記述する * @param \Illuminate\Console\Scheduling\Schedule $schedule * @return void */ protected function schedule(Schedule $schedule) { // クロージャに直接処理を書くことも可能 $schedule->call(function () { echo "hello!\n"; }); // batch:testを毎時実行し、出力先を$filePathに指定する $schedule->command('batch:test') ->sendOutputTo($filePath) ->hourly(); } /** * Register the commands for the application. * * @return void */ protected function commands() { $this->load(__DIR__.'/Commands'); require base_path('routes/console.php'); } } |
上記の
sendOutputTo
や
hourly
以外にも様々な制御が可能です。公式ドキュメントで網羅されていますので、是非見てみてください。
あとはcrontabに1行追加するだけで、
Kernel.php
に登録したコマンドがそれぞれ実行されるようになります。
1 2 3 4 5 6 7 8 9 10 11 | $ crontab -e # do daily/weekly/monthly maintenance # min hour day month weekday command */15 * * * * run-parts /etc/periodic/15min 0 * * * * run-parts /etc/periodic/hourly 0 2 * * * run-parts /etc/periodic/daily 0 3 * * 6 run-parts /etc/periodic/weekly 0 5 1 * * run-parts /etc/periodic/monthly # 以下1行を追記する * * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1 |
これで完了です。
※ 今回初めてAlpine Linuxのcrontabを触りましたが、Redhat系のcrontabと比べてコメントが親切ですね…
さいごに
以前はcrontabをテキストファイルとしてリポジトリに登録したり、もしくはサーバ上のcrontabを直接編集したりすることが私はほとんどでした。こうやってコード上で管理でき、分かりやすく制御できるのは素晴らしいですね。