Laravelでスケジュール実行する方法。外部DBのテーブルを定期的にローカルのDBに同期。

  1. プログラミング

Laravelはプログラムを定期実行できる。

サイトマップを定期的に更新したり、DBの同期をしたりするときに役立つ。
本記事では、外部DBのテーブルを、毎日8:00時にローカルのDBに同期することを目標とする。

「スケジュール実行の方法だけ知りたい!DBの接続の話はどうでもいい!」
という方は手順4からみていただければと思います。

1.外部接続可の権限を持つユーザを作成

外部DBにアクセスするには、まず外部からの接続を許可しているユーザを外部DBに作成する必要があります。
この方法については、わかりやすい記事があったのでこちらを確認してください。

2.外部DBの接続情報を定義

Laravelは、複数のDBに接続できます。

config/database.phpを以下のように修正。

mysqlは、普通に今まで使っていたローカルのDBの接続情報ですね。
今回、2つ目のDBとして、mysql_outerを定義しました。

各項目は、外部DBの情報を記述してください。

これにより、今後
DB::connection(‘mysql_outer’)->table(‘テーブル名’)->get();
のようにして、2つ目のDBにアクセスできます。

3.DBを同期するコマンドを生成

まず、下記のコマンドを叩き、「DBを同期するコマンド」syncdbを生成する。

syncdbは今回適当につけた名前なので他の名前でも大丈夫です。

上記コマンドを叩くと、App/Console/Commandsの中に、新規ファイルが生成されます。
このファイルを以下のように修正します。

15行目で、コマンドを実行する際のコマンド名、22行目がコマンドの説明分です。

41行目で、外部DBのテーブルのデータをすべて取得し、ローカル変数に格納。
42から45行目は、syncDataをオブジェクト型から配列に変換してます。
これは、後にsyncDataをinsert()に渡す際、オブジェクト型のままだとエラーが発生するためです。

46行目で、ローカルDBのテーブルを一度空にする。

48から50行目で、ローカル変数syncDataに格納されているデータをinsertしていってます。
foreachでわざわざ回しているのは、syncDataの配列の要素が多い場合、一度のinsertですべてやろうとするとtimeoutやらメモリーオーバーなんたらかんたらみたいなエラーがでるためです。だから、1000個ずつに分割してinsertしてます。

これで、同期を行うコマンドができました。
あとは、このコマンドを定期的に実行するためのスケジュール設定をしていくだけです。

4.スケジュール設定

編集するファイルは、App/Console/Kernel.phpです。

下記のように、記述する。

16行目で、手順3で作成したコマンドのクラスファイルを指定。

27行目。
$schedule->command(‘command:syncdata’)->dailyAt(‘8:00’)->emailOutputTo(‘laraveldaisuki@test.co.jp’);

dailyAt(‘実行したい時間’)で、command(‘実行したいコマンド’)を意味している。
emailOutputTo()で、スケジュール実行の通知を受け取りたいメールアドレスを指定できます。

5.cronの設定

crontab -eコマンドで、cronの設定ファイルを開き、下記のように記述する。

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

これにより、手順4にて設定したスケジュール情報を毎秒確認し、実行するタイミングのものがあればそれを実行するようになる。
path-to-your-projectの箇所は、あなたのLaravelプロジェクトのトップディレクトリのパスに修正してください。

あと、注意点ですが、phpコマンドのパスを指定しないと実行されない場合があります。
xserverの場合は、設置しないといけないです。
そのときは、以下のようにphpコマンドのパスを指定しましょう。

* * * * * /bin/php7.2 /path-to-your-project/artisan schedule:run >> /dev/null 2>&1

自分のphpのバージョンを調べるときは、php -vコマンドで調べてください。

以上です。
これで、動くはずです。

関連記事