【Laravel】タスクスケジュールでバッチ処理を自動実行する

## はじめに

夜間に日次や月次のバッチ処理を行う、、、など定期的な処理を実行したい場合、Laravelの独自カスタムコマンドとタスクスケジュールを利用することで、便利に実装することができと学んだのでまとめておく。

通常Linux系のOSで定期的な処理を自動で実行する場合、タスク毎にcronエントリーを追加することでタスクを実行する。
Laravelのタスクスケジュールを使用する場合もcron等を使ってタスクを実行する必要はあるが、cronエントリーの追加は一つだけで済む。

※Laravelのバージョンは8を利用。

## 手順

全体の流れは以下の通り。

1. バッチファイル（独自カスタムコマンド）を作成する。
2. タスクスケジュールを定義する。
3. cron等に登録して自動で実行できるようにする。

ひとつずつ説明していく。

## 手順①：バッチファイルを作成、編集する

### ファイルの作成

まずは下記コマンドを実行して、バッチファイル（独自カスタムコマンド）を作成する。

```php
php artisan make:command クラス名

// 例 （Readoubleより引用）
php artisan make:command SendEmails
```

実行すると、`app/Console/Commands`配下にファイルが作成される。

作成時点でのファイルの中身は以下の通り。

```php
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class SendEmails 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`：artisanコマンドとして実行するコマンド名。
- `$description`：コマンドの説明。
- `construct`：クラスが作られるときに処理される内容。handleメソッドの前に行いたい処理があれば記述する。
- `handle`：実際の処理を記述する。

### ファイルを編集する

試しに以下のように編集してみる。

```php
/**
 * The name and signature of the console command.
 *
 * @var string
 */
protected $signature = 'command:sendMail';

/**
 * The console command description.
 *
 * @var string
 */
protected $description = '(test) send mail';

// 中略

/**
 * Execute the console command.
 *
 * @return int
 */
public function handle()
{
    echo 'Send an Email!!';
}
```

### コマンドの確認と実行

 `php artisan list` とコマンドを実行してみると、 `Artisnan` コマンドとして登録できていることを確認できる。

```php
php artisan list

// 中略
command
  command:sendMail     (test) send mail
```

実際にコマンドを実行すると、出力を確認できる。

```php
php artisan command:sendMail

// 出力結果
Send an Email!!
```

### バッチコマンドに引数を渡す

バッチコマンドには引数を渡すこともできる。

引数を渡す場合の記述方法は以下の通り。

```php
// signatureへの記述
protected $signature = 'command:sendMail {name}';

// 引数を任意とする場合
protected $signature = 'command:sendMail {name?}';


// handleメソッドで引数を受け取る
public function handle()
{
    $name = $this->argument('name');

    echo "Send an Email to {$name}!!";
}
```

そしてコマンドを実行するときに引数となるパラメータを渡す。

```php
php artisan command:sendMail taro

// 実行結果
Send an Email to taro!!
```

## 手順②：タスクスケジュールを定義する

手順①で作成したバッチコマンドを定時で実行できるように、タスクスケジュールに登録する。

タスクスケジュールの内容は `app/Console/Kernel.php`に記述する。

 `Karnel.php` の初期状態は以下の通り。

```php
<?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 = [
        //
    ];

    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        // $schedule->command('inspire')->hourly();
    }

    /**
     * Register the commands for the application.
     *
     * @return void
     */
    protected function commands()
    {
        $this->load(__DIR__.'/Commands');

        require base_path('routes/console.php');
    }
}
```

この `schedule` メソッドにタスクスケジュールを登録する。

```jsx
$schedule->command('command:sendMail')->monthlyOn(1, '09:00');
```

上記の例では、毎月1日の9時に実行するよう指定した。

送信するタイミングなどなど、たくさんのオプションが用意されているので、詳しくはReadoubleを参照。
[Laravel 8.x Artisanコンソール](https://readouble.com/laravel/8.x/ja/artisan.html)

## タスク実行の登録

Laravel側で行うことは以上。

あとはこのタスクをcronに登録するなり、AWSでデプロイしているならタスクスケジューラを使用するなりして、このタスクが実行されるように登録すればバッチ処理の実装は完了となる。

## さいごに

Laravelの自作コマンドを利用すれば、バッチ処理など自動で実行する処理に用いる一方で、手動でコマンドを実行して使うこともできて便利だと思った。

またcronというものを今回初めて知ったので、どのような場面でどのように使われているのか、実際に見てみたい。

## 参考記事
https://readouble.com/laravel/8.x/ja/artisan.html

https://readouble.com/laravel/8.x/ja/scheduling.html

https://www.rail-c.com/laravel%E3%81%AE%E3%82%BF%E3%82%B9%E3%82%AF%E3%82%B9%E3%82%B1%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%E3%81%A7%E5%AE%9A%E6%9C%9F%E5%87%A6%E7%90%86%E3%82%92%E8%87%AA%E5%8B%95%E5%AE%9F%E8%A1%8C/

https://syoblog.com/laravel-batch/

https://codelikes.com/laravel-batch-command/