0
0

More than 3 years have passed since last update.

Task Schedulerでユーザーごとに、データベースに保存した時間にコマンドを実行する

Last updated at Posted at 2021-08-30

プログラミング初心者です。

開発環境

Laravel 5.8
PHP 7.3.24
MAMP

やりたいこと

Kernel.phpに、ユーザーごとに「毎日」、かつ「データベースに保存した時間」にコマンドを実行させるように実装したい。
参考サイトこちら

1 Migrate

まずユーザー側から設定された時間を保存するための、migrateファイルを作成します。

create_samples_table.php
class CreatePushesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('samples', function (Blueprint $table) {
            $table->bigIncrements('id');
            //UserTableのidを保存するカラム
            $table->unsignedBigInteger('user_id');
            //時間を保存するカラム。型は時間なのでtime。時間を設定しない場合もあるためNULLで保存できるようにしています。
            $table->time('sample_time')->nullable(true);
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('samples');
    }
}

2 Model

Modelを作成します。

Sample.php
class Push extends Model
{
    protected $guarded = array('id');
    public static $rules = array(
        'user_id' => 'required',
        'sample_time' => 'required',
    );

    //user_idカラムにUser Modelのidを保存したいため、リレーションします。
    public function user()
{
    //User.phpにもSample.phpとhasOneでリレーションしています。
    return $this->belongsTo('App\User');
}
}

3 Kernel.php

Kernel.phpはLaravelには二つありますが、app/Console/Kernel.phpを開いてください。
そしてすでにSample Modelのsample_timeに時間が保存されたとします。

Kernel.php
namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
//Sample.phpデータを使いたいため
use App\Sample;


class Kernel extends ConsoleKernel
{
    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    //自分で作成したコマンドの登録をします。
    protected $commands = [
        Commands\SampleCommand::Class,
    ];

    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    //タスクをスケジュールする
    protected function schedule(Schedule $schedule)
    {
        //ここでは毎日、ユーザーが設定した時間に実行するというスケジュールにします。
        $samples = Sample::all();
        foreach($samples as $sample) {
            //時間を文字列にしています
            $sampletime = date('H:i',strtotime($sample->sample_time));
            $schedule->command("SampleCommand {$sample->user_id}")->dailyAt($sampletime);
        }
    }

解説

protected function scheduleの中身を解説します。


$samples = Sample::all();

Sample Modelの全てを取得し、$samplesに代入します。

foreach($samples as $sample)

foreachでsamples を $sampleとして繰り返します。

$sampletime = date('H:i',strtotime($sample->sample_time));

時間をdateメソッドとstrtotimeメソッド使って文字列に変えています。
なぜならdailyAtメソッドの型は文字列でなければなりません。そのためtime型からstring型に変える必要があります。
参考サイトこちら

$schedule->command("SampleCommand {$sample->user_id}")->dailyAt($sampletime);

・ $scheduleはprotected function scheduleの引数です。
・ commandメソッドに実行したいコマンド名を入力します。そして今回は”ユーザーごとにコマンド実行”なので引数を設定していて、$sampleからuser_idカラムを取得しています。引数の設定は作成したコマンドファイルの中で実装しています。
・ dailyAtメソッドですが、毎日実行という意味です。メソッド内には文字列型に変えた$sampletimeが入ります。Task ScheduleにはスケジュールオプションがありDocumentに載っておりますので、参考にどうぞ。

4 Cronの設定

  • Kernel.phpのタスクを実行するには、cronの設定が必要です。 (laravelのversion 8.xからだと設定は必要がないみたいです。)
  • Vimで編集するのですが、文面だけでは説明が難しいため、こちらのサイトがわかりやすいため、参考にどうぞ。
  • 米印の部分は*****5個のままで大丈夫です!
  • 実行するコマンドファイルにLogを記載するように実装すると実行されたかどうか分かりやすいです。そして設定した時間に実行されたら成功です!

もし、cronがそもそもちゃんと動くのかを確認したい場合、私がした実装はコメントアウトして、参考サイトのようにeveryMinuteメソッドで毎分実行されるように実装すれば早く確認できます。
あと、cronは設定すると動き続けてしまうので、当分使わないなと思ったら消してもいいと思います。

ここまでお疲れ様でした!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0