Laravel タスクスケジュール
こんにちは。webチームの黒岩です。
最近の業務でlaravelの定期実行を組み込む機会がありまして、
今回はLarvelフレームワークに搭載された便利な機能の一つである「タスクスケジュール」について解説していこうと思います。
タスクスケジュールとは
Laravelには、指定の処理を指定した時間間隔で定期的に実行する機能が組み込まれています。
その定期実行のことを、タスクスケジュールと呼ぶことにします。
今回はスケジュール実装手法の中でも比較的有名な、
「コマンド」によるスケジューリングについて解説していきます。
コマンドについても少しだけ解説
Laravelでよく使うこちらのコマンド
php artisan ・・・
俗にいうartisanコマンドですね。
laravelのcommandというものを作ると、そのcommand内で書かれた関数をartisanコマンドで実行することが可能となります。
つまり、オリジナルのartisanコマンドが作れるということです。
このコマンドを今回のスケジュールで利用することで、テストも容易になります。
環境・前提知識
Laravel 8.60.0
- オブジェクト指向について理解のある方
- laravelのコントローラーやモデルを触ったことのある方
設定方法
タスクスケジュールの実装は案外かなり簡単にできます。
今回はシンプルに、「Hello World」と毎日9時にテキストファイルに記入するという機能を実装しましょう。
1: コマンドの新規作成
先ずはコマンドを自作していきましょう。プロジェクトディレクトリ内で以下のコマンドを入力してください。
php artisan make:command SayHello
これを入力すると、app/Console/Commandsディレクトリに、
SayHello.phpが生成されていると思います。
中身を見てみましょう。
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class SayHello extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'command:name';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Command description';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
return 0;
}
}
これからこのファイルをいじってオリジナルコマンドを生成していきましょう。
コマンドファイルの詳細
少しこのコマンドファイルについて解説します。
$signature (: 14)
実際に入力する際のコマンドの名前
$description (: 21)
コマンドについての詳細の記述。--helpコマンドを入力した際の説明に使う
construct() (: 28)
名前の通りコンストラクタ。今回は使わない
handle() (: 38)
ここにコマンドが入力された際に行う実際の処理を記述する
コマンドファイルの編集
SayHello.phpを編集するにあたり、今回実装する機能をおさらいしましょう。
テキストファイルに「Hello World」と記入する
これだけですね。シンプルです。
肝心なテキストファイルの場所についてですが、/storage/app/
フォルダ直下に
hello.txt
という名前のテキストファイルを作成してください。
これで準備が整いました。
処理のソースコード
まずテキストファイルに記入する処理ですが、少しづつ掘り下げていきましょう。テキストファイルに記入処理を行うには当然テキストファイルを読み込まないといけません。
今回は折角laravelを利用しているので、laravelフレームワークにある機能を使いたいところ。
そこで今回は、Storageクラスを使いましょう!
Storageクラスを使うために、6行目ぐらいに以下のコードを入れてください。
use Illuminate\Support\Facades\Storage;
先ほどstorage/appフォルダにhello.txtを作ったと思いますが、
Storage関数を使えば、そのファイルにアクセスして、書き込むまでを一行でできるんです!
Storage::put('hello.txt', {書き込む文章});
これは、storage/appフォルダ内の第一引数で指定したファイルに第二引数に書いた内容を書き込んで保存する処理となります。
したがって、handle関数内に書く内容はこれだけで済みます。
$text = 'Hello World.';
Storage::put('hello.txt', $text);
すごく簡単ですね!
コマンド名とコマンドの説明
php artisan に続くコマンド名と、コマンドについての説明ですが、好きなもので構いませんが、一例を紹介しましょう。
protected $signature = 'sayhello';
protected $description = 'Put Hello World to txt file.';
これでコマンドファイルの編集は終わりです。
最後に完成したSayHello.phpを載せておきます。
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Storage;
class SayHello extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'sayhello';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Put Hello World to txt file.';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
$text = 'Hello World.';
Storage::put('hello.txt', $text);
}
}
後はコマンドを毎日9時に動かせるように設定を行うだけです。
コマンドの適用
app\Console\Kernel.phpを開いてください。
ここにコマンドを適用させていきます。
今回は、毎朝9時に行うので、その処理も書いていきましょう。
とはいっても、実際に書くのは1行だけですが。
Kernel.phpの中に、schedule
関数があると思います。その中に、この一行を追加しましょう。
$schedule->command('sayhello')->timezone('Asia/Tokyo')->dailyAt('9:00');
メソッドを一つずつ解説していきます。
timezone('Asia/Tokyo')
ご想像の通り、標準時を日本の東京に設定します。無くても大丈夫ですが時間の正確性を上げるのとバグを減らすために設定しておいて損はありません。
dailyAt('9:00')
daily、つまり毎日。ここで毎朝9時に呼び出す設定を行います。
他にも毎分とか毎月とかも設定できるので後で一通り列挙します。
これで完了です!最後にコマンドがしっかり動くか、テストをしてみましょう。
テスト
以下のコマンドを打ってみて、storage/app/hello.txtにHello World.
と表示されたら勝ちです。
php artisan sayhello
あとはこのタスクをcronに登録するなり、AWSでデプロイしているならタスクスケジューラを使用するなりして、このタスクが実行されるように登録すればバッチ処理の実装は完了となりますが、今回はファイルの作成とコマンド作成が軸なので省かせていただきます。
メソッド一覧
最後に、タスクスケジュールのメソッドの一部を紹介して終わろうと思います。
メソッド | 説明 |
---|---|
->daily(); | 日付が変わったタイミングで毎回実行 |
->weeklyOn(1, '8:00'); | 毎週月曜日の8:00時に実行 |
->monthlyOn(4, '15:00'); | 毎月4日の15:00に実行 |
->hourly(); | 毎時タスク実行 |
->hourlyAt(17); | 1時間ごと、毎時17分にタスク実行 |
->everySixHours(); | 6時間毎にタスク実行 |
->sundays(); | 日曜だけに限定して実行されるように設定(一週間全部あります) |
->days(array|mixed); | 特定の日にちだけに限定して実行されるように設定 |