言語(PHP他)PHPLaravel
更新日 : 2020年9月1日
投稿日 : 2020年4月30日

Laravelで定期実行処理を実装する

Laravelで定期実行処理を実装するの画像

こんにちわ、PHPエンジニアのエンジニア婦人(@naho_osada)です。
私はPHPエンジニアとして7年~の経験があります。WordPressは2年半~の経験があります。その他、jQuery、HTML、CSSも使用します。
ここでは主に過去に納品した案件や自サイト運営(エンジニア婦人ノート)で遭遇したことについて書いています。

システムを作っていると、「定期的に、毎日、自動で実行してほしいな」という処理が出てきます。
例えばTwitterやLINEのbot、一日ごとに集計してその結果をサーバーに保存するなど。

ここではLaravelで定期実行処理をさせたいときに、どういう実装をするのかということを書いていきます。

※ここで使用しているLaravelのバージョンは「6.18.3」です。

Laravel版定期実行の設定方法

crontabに以下の設定をします。

* * * * * cd Laravelプログラム本体の場所 && php artisan schedule:run >> /dev/null 2>&1

これは「Laravelに備わってる定期実行モードを毎分実行するよ」という指示です。

Laravelで作る定期実行処理は「この1つの登録だけ」です。

最後の「>> /dev/null 2>&1」は、「標準エラー出力の結果を標準出力にマージして、/dev/nullに破棄」ということ意味です。
これをつけないと実行結果がログに出力されてサーバー容量圧迫してしまう場合が…!なんせ毎分実行監視するので、何もやらなかった場合の結果などのログがすさまじいことになります。

参考:PHPの定期実行の設定方法

Webサーバーで定期実行と言えば、指定のプログラムをLinuxのCrontabで〇日〇時〇分に実行する設定を入れて、指定通り動作させるものです。
例えば、以下のような書き方をします。

crontab -e
* * * * * /usr/bin/php /var/www/html/cron/index.php

「アスタリスク(*)」は左から「分、時、日、月、曜日」を示します。上記のように全部「アスタリスク(*)」の場合は毎分実行です。
※Cronそのものの詳しい設定方法は省略します。

Laravelの定期実行処理を作ってみる

※以下は「みんなのきょうのごはん」のTwitterbotプログラムを一部抜粋しています。

定期実行のプログラムを作る

コマンドから実行ファイルを生成します。

php artisan make:command TwitterBot

これを実行すると「/app/Console/Commands」にTwitterBotファイルが生成されます。
生成したファイルを開いて、「$signature」の値を「batch:twbot」にします。登録するbatch名称なので、他のbatch名とかぶらなければ問題ありません。

namespace App\Console\Commands;

use Illuminate\Console\Command;

// TwitterOAuthライブラリを指定
use Abraham\TwitterOAuth\TwitterOAuth;

class TwitterBot extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    // batch名称 batch:〇〇〇 でかぶらなければなんでもいい
    protected $signature = 'batch:twbot';

    /**
     * The console command description.
     *
     * @var string
     */
    // この処理の説明文 説明できていればなんでもいい
    protected $description = 'みんなのきょうのごはんTwitterBot';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Twitterで朝、昼、おやつ、夜、その他の内容のTweetを1時間に1回実行する
     *
     * @return mixed
     */
    public function handle()
    {
        // 定期実行させたい処理を書く
        // 省略
    }
}

定期実行ファイルのテスト実行

以下のコマンドで実行の確認ができます。「batch:$signatureで設定した名称」です。

php artisan batch:twbot

実行の確認はhandle()内でechoでもなんでもしておけばいいと思います。
実行確認が取れたらやらせたい処理を書いていきます。

補足:VSCodeでデバッグ可能

このコマンドからの実行でも、VSCode(VisualStudioCode)からデバッグできます。ブレークポイントも使えるので、是非やってみてください。

XDebugやVSCodeを使ったデバッグ関連の記事はこちらにあります。

Kernel.phpに定期実行のプログラムを登録する

定期実行のプログラムができたら、「このプログラムを定期実行するよ」と指定します。
「/app/Console/Kernel.php」を編集します。

namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        // TwitterBotクラスを追加
        TwitterBot::class,
    ];

    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        // TwitterBot 1時間おきに実行
        $schedule
                ->command('batch:twbot')
                ->hourly();
    }
    // 以下省略
}

毎分(->everyMinute();)、指定時刻(->dailyAt(’13:00′);)の設定などができます。設定できるものは公式ドキュメントにあります。
ここでは1時間おきに設定しています(TwitterBotが毎分動いていたらちょっとうざったい)。

サーバーに定期実行処理を設定する

上にも書きましたが、サーバーにcrontabで設定をします。

crontab -e
* * * * * cd Laravelプログラム本体の場所 && php artisan schedule:run

これで定時実行されているかの確認ができます。

Laravel版定期実行処理のいいところ

勘のいい方はお気づきかもしれませんが、Laravelフレームワークを使って定期実行処理をしたい場合、Linuxのサーバーの設定はCrontabに

* * * * * cd Laravelプログラム本体の場所 && php artisan schedule:run

だけでいいのです。これは「サーバーのcrontabにLaravelで実行させたい処理を全部書く必要がない」ということを意味します。
つまり、crontabに書くのは1つだけでよく、定期処理を追加したいときはLaravel側の処理を追加するだけでいい
定期実行処理が増えてもLaravel側のファイルを修正するだけで、crontabを毎回触る必要がありません。どこかにサーバーを移転するときも定期処理の登録漏れを防ぐことができます。

私はこれまでcrontabにwgetで特定のURLを叩いたり、「/usr/bin/php /var/www/html/cron.php」で直接プログラムを実行する方法を取ってきましたので、Laravel版のものはとても楽だなー!と感じました(*’ω’*)

まとめ

  • batch処理の保存先は「/app/Console/Commands」
  • 「/app/Console/Commands」に追加したら「/app/Console/Kernel.php」にコマンドを追加する
  • Laravel版定期実行処理はcrontabに1つ登録するだけでいい
  • 時間指定などはLaravel側のプログラムで設定できる

参考になれば幸いです(‘ω’)ノ

参考