Laravel6で自動処理（タスクスケジュール）を実装する

Laravel案件を担当している時に、サーバー側で定期的に自動処理をしてほしいというバッチ処理的な依頼がありました
その時に使ったタスクスケジュールと機能が便利だったので、実装の流れを備忘録として記事にしてみました

# 環境

- Laravel 6.20.34
- Ubuntu 20.04.2 LTS（homestead）


# どうやって実装するか

cronを簡単に利用することのできるLaravelのタスクスケジュールという機能を使うことで実装が可能です


# この記事で実装するもの

この記事ではLaravelタスクスケジュールの使い方を理解するために、storage配下のlogファイルへ現在日時を5分毎に残す処理を実装してみます


# 仮想環境へログイン

今回はhomesteadでLaravelの環境構築をしているので、仮想環境へログインしておきます

```
vagrant ssh
```


#crontabへエントリー追加

Laravelではcrontab(crontable)のエントリーがひとつだけで完結します
各タスクのスケジュール設定はLaravelファイル内に記述することで実装できるようになっているためです
<br>
まずエントリーを追加するために、crontabの編集を開始します

```
crontab -e 
```
<br>
すると、vimエディタが開くので、insertモードにして下記エントリーを記述します

```
* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1

#　homesteadなら以下のような感じ
* * * * * cd /home/vagrant/code/app && php artisan schedule:run >> /dev/null 2>&1
```
この記述で、Laravelのprojectフォルダに移動して、artisanコマンドでタスクスケジュールを実行するという指示がcronに追加されたことになります

:::note warn
path-to-your-projectの箇所はLaravelが保存されているディレクトリに応じて変更します
:::  


# タスクスケジュールを設定する

cronの準備ができたので、Laravel側のタスクスケジュールを設定していきます
タスクスケジュールの設定は大きく分けて以下の2つの流れで実装します

1.　タスク実行するための新規artisanコマンドを登録する
2.　登録したartisanコマンドを自動実行するためのスケジュールを設定する


## 1.　タスク実行する新規artisanコマンドを作成する

AppApp\Console\CommandにAddTimeToLog.phpというファイルを生成します

```
php artisan make:command AddTimeToLog
```

AddTimeToLog.phpを以下のように書き換えます

```php:AppApp\Console\Command\AddTimeToLog.php
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
//　①以下useを追記
use Carbon\Carbon; 
use Illuminate\Support\Facades\Log;

class AddTimeToLog extends Command
{
    protected $signature = 'command:AddTimeToLog'; //　②変更

    protected $description = 'Add Current Time To Log'; //　③変更

    public function __construct()
    {
        parent::__construct();
    }

    public function handle()
    {
        // ④追記
        $current = Carbon::now('Asia/Tokyo');
        Log::info($current);
    }
}
```

:::note info
1. 現在日時を取得するのに便利なCarbonライブラリとLogを残すためのファサードをuseを使って宣言します
2. artisanコマンドの名前を入力します。わかりやすい名前であれば大丈夫です
3. artisanコマンドの説明を入力します。わかりやすい説明であれば大丈夫です
4. handleメソッドの中には実行したい処理を記述します。今回はCarbonで現在日時を取得して、Logファイルに残すという簡単な処理のみ記述しておきます
:::
<br>
これでaritsanコマンド新規登録が完了しました。
念の為、ちゃんと登録されているか確認します。

```
php artisan list
```

commandのところに先ほど設定した名前と説明を含めて登録されているのが確認できます
![スクリーンショット 2021-11-20 9.36.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1006362/9ac980c6-a282-974a-53fa-e59682069d60.png)

下記コマンドで実行してみます

```
php artisan command:AddTimeToLog
```

laravel.logを確認すると、ちゃんとログが残っています

```:storage/logs/laravel.log
[2021-11-14 16:57:01] local.INFO: 2021-11-14 16:50:00  
```

では次にこのコマンドの実行を自動で実行させるように設定していきましょう


## 2.artisanコマンドを自動実行するスケジュールを設定する

App\Console\Kernelクラス内に、タスクスケジュールを設定することでartisanコマンドの自動実行が可能です

Kernel.phpを以下のように書き換えます（といっても追記するのはscheduleメソッドの中だけ）

```php:AppApp\Console\Kernel.php
<?php

namespace App\Console;

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

class Kernel extends ConsoleKernel

    protected $commands = [
    ];

    protected function schedule(Schedule $schedule)
    {
        $schedule->command('command:AddTimeToLog')-> everyFiveMinutes(); //　①追記
    }

    protected function commands()
    {
        $this->load(__DIR__.'/Commands');

        require base_path('routes/console.php');
    }
}
```
:::note info
1. Artisanコマンドをスケジュールするための、commandメソッド（引数は実行したいコマンド）を追記します。また5分毎に実行するオプションをチェーンします
:::

これだけで、タスクスケジュールの設定が完了しました。

:::note warn
なお、他の記事だと$commands変数の配列に、コマンド登録しないといけないという記述が多くありました。
しかし、実際は同ファイル内（Kernel.php）のcommandsファンクションのloadメソッド呼び出しにより、app/Console/Commands　ディレクトリ内のすべてのコマンドが自動的にArtisanに登録されているので追記しなくても動くようです。
:::
>
Because of the load method call in your console kernel's commands method, all commands within the app/Console/Commands directory will automatically be registered with Artisan. In fact, you are free to make additional calls to the load method to scan other directories for Artisan commands:

https://laravel.com/docs/6.x/artisan


# Logファイルを確認する
  
最後にLogファイルを確認すると以下のような感じです

```:storage/logs/laravel.log
[2021-11-14 16:57:01] local.INFO: 2021-11-14 16:50:00  
[2021-11-14 16:58:02] local.INFO: 2021-11-14 16:55:00  
[2021-11-14 16:59:02] local.INFO: 2021-11-14 17:00:00  

```
  
  
# 参考記事
https://readouble.com/laravel/6.x/ja/scheduling.html
https://reffect.co.jp/laravel/laravel-task-schedule-cron
https://laravel.com/docs/6.x/artisan