CakePHP3によるバッチ処理(定時処理)

シェアする

CakePHP3を利用しバッチ処理(定時処理)を実行する方法を紹介します。
Linuxでcronを実行する場合、CakePHPを利用することによって詳細な処理が実行できます。

利用の処理について

・データベースの更新
(EX:顧客管理などの不要なデータの削除)
・データベースからの必要とするデータの抽出
(EX:メール送信先の抽出など)
・バッチ処理(定時処理)を行う

CakePHP3を利用することによる利便性

・定時処理と手動運用の同時化が行える
・LinuxのShellでは行えない処理をCakePHP3で詳細に行える
・手動運用、定時運用が容易です。
・Webで受けた処理でも思い処理を定時処理化ができて、サーバーの負担を減らさせます。

利用方法

例文はファイル容量計算をする定時処理です。
一部ソースでは便宜上、日本語説明をしている部分があります。

/src/shell/FileStartShell

コンソール上で実行するシェルを作成するには、src/Shellディレクトリにプログラムを作成する必要があります。

namespace App\Shell;

use Cake\Console\Shell;
use Cake\Log\Log; 
use Cake\Controller\Component; 
use Cake\Controller\ComponentRegistry; 
use App\Controller\Component\CommonComponent; 

class FileStartShell extends Shell {
  public function initialize() {
    $this->Common = new CommonComponent(new ComponentRegistry());
  }

  public function main() {
    $ca = $this->name . ':' . __FUNCTION__ . ':';
    $this->log($ca . 'START', LOG_DEBUG);

    $file = $this->Common->fileStart(null);
    if ($file['err']) {
      $this->log($ca . 'ファイル容量計算が成功しました。', LOG_DEBUG);
    } else {
      $this->log($ca . 'ファイル容量計算が失敗しました。', LOG_ERR);
    }
    $this->log($ca . 'END', LOG_DEBUG);
  }

}

ソースの説明

ファイル名はFileStartShell.phpと、必ずShellが必要です。

3行目:use Cake\Console\Shell;は必須です。
4行目:Shallで実行するのでログ出力用です。
5行目~7行目:今回はComponentを利用しています。
9行目:クラスの作成、Shellを拡張しています。
11行目から13行目:CommonComponentを登録して利用できるようにしています。
15行目:Shellとして動作するmain関数を利用します。
各行:$this->logはログ出力です。
19行目:CommonComponentを利用してファイル容量計算をし、データベースに登録します。

shellの実行

実行

/topass/bin/cake file_start

実行結果

ファイル容量計算が成功しました。

シェルを実行するシェルクラスには、クラス名にShellサフィックス(接頭辞)を付けて、ファイル名と一致する必要があります。
実行時にシェルに引数を付けないと、main()メソッドが呼ばれて処理が実行されます。
main()メソッドはシェル実行時に他のコマンドや引数が無いときに、いつでも呼ばれるメソッドです。

Shellに引数をしていする場合

前述したmain()以外のメソッドを使用する場合は、シェル実行時にメソッド名を引数に指定して実行する必要があります。

namespace App\Shell;

use Cake\Console\Shell;
use Cake\Log\Log; 
use Cake\Controller\Component; 
use Cake\Controller\ComponentRegistry; 
use App\Controller\Component\CommonComponent; 

class FileStartShell extends Shell {
  public function initialize() {
    $this->Common = new CommonComponent(new ComponentRegistry());
  }

  public function main() {
    $ca = $this->name . ':' . __FUNCTION__ . ':';
    $this->log($ca . 'START', LOG_DEBUG);

    $file = $this->Common->fileStart(null);
    if ($file['err']) {
      $this->log($ca . 'ファイル容量計算が成功しました。', LOG_DEBUG);
    } else {
      $this->log($ca . 'ファイル容量計算が失敗しました。', LOG_ERR);
    }
    $this->log($ca . 'END', LOG_DEBUG);
  }

  public function sample($name)
  {
        $this->log('私の名前は'.$name.'です。');
  }

}

実行

/topass/bin/cake file_start sample sato

「passto/bin/cake [シェルプログラム] [メソッド名] [メソッドの引数の値]」と指定します。

実行結果

私の名前はsatoです。

CRONの登録

CRONに登録します。
毎月1日0時に実行します。

$ sudo vim /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
0 0 0 1 * * root      /topass/bin/cake file_start

【注意点】

/bin/cakeには実行権限を与えておくことが必要です。
権限を与え忘れる人が多いです。

まとめ

Componentを利用することにより、ShallとControllerから操作可能となり、生産性と品質が向上します。
また、Webで重い処理がある場合、バッチ起動をさせて運用すると、サーバーの負荷率を下げることも可能です。