CakePHPにバッチ処理を組み込むには

CakePHPで構築したアプリケーションにおいても、バッチ処理を組み込みたいケースはよくある話かと思います。僕は、CakePHPデビュー戦でいきなりバッチ処理を必要とするアプリケーションを作ろうとしてしまったので、どういうふうに組み込むのか、作法がわからず戸惑ってしまったわけですが。

いまだに戸惑いつつも、どうやらこういうことらしいというのは何となくわかったので、備忘録として書きます。

(CakePHP1.2ベースで書いてます。1.1は違うかも)

バッチ処理PHPファイルの置き場所

ドキュメントルートにCakePHPの各種ファイル群を設置すると、ドキュメントルート配下に以下のようなディレクトリができているはず。

  • /app/vendors/shells
  • /vendors/shells

どうやら、このどっちかに設置するようです。
どっちに設置しても動作するみたいですが、どう使い分けるのが作法的に正しいのかは、いまのところ不明。僕は/app/vendors/shellsの方に設置しました。

バッチ処理PHPの書き方

バッチ処理の名前を"hoge"とつけたいとすると、PHPのファイル名は、

hoge.php

とします。

hoge.phpの内容は、以下のようにします。

class HogeShell extends Shell {
function main() {

(実行したい処理の内容を書きます)

}
}

後述する起動方法でこのバッチ処理を起動すると、上記で定義したmain()というメソッドが実行されます。

さて、実際問題としては、バッチ処理内でDBにアクセスしたいというケースがほとんどと思われます。
CakePHPでは、DBのテーブルにアクセスする命令を個別のソース内にゴリゴリ書くのではなく、各テーブルに対応させて作成した「モデル」を介してアクセスするのが作法です。この作法は、バッチ処理でも同じです。

たとえば"Post"というモデルをバッチ処理内で利用したいときは、以下のように書きます。

class HogeShell extends Shell {
var $uses = array('Post');

function main() {

(実行したい処理の内容を書きます)

}
}

ここで出てくる"$uses"という変数は、コントローラーから別のモデルを利用したいときにも用いられるものらしいです。

バッチ処理の実行

作成したバッチ処理を実行する方法ですが。
とりあえず今はMAMPの開発環境上に構築しているので、その前提で書きます。

仮に、

/Applications/MAMP/htdocs/test

の下にCakePHPのファイル群を設置しているとすると、ターミナルで以下のように入力することで、バッチ処理を実行できます。

/Applications/MAMP/htdocs/test/cake/console/cake hoge -app /Applications/MAMP/htdocs/test/app/

これにより、/app/vendors/shells/hoge.php内で定義されたHogeShellクラスのmain()メソッドが実行されます。

MAMP環境で実行すると発生するエラーの解決法

上記の方法でバッチ処理を作成し、テスト的にターミナルから実行!
…すると、なにやらWarningが出てくるかと思います。

Warning: mysql_connect(): Can't connect to local MySQL server through socket '/var/mysql/mysql.sock' (2) in /Applications/MAMP/htdocs/blogseeq/cake/libs/model/datasources/dbo/dbo_mysql.php on line 118

Warning: mysql_select_db(): supplied argument is not a valid MySQL-Link resource in /Applications/MAMP/htdocs/blogseeq/cake/libs/model/datasources/dbo/dbo_mysql.php on line 123

...

こんな感じに。

これ、なんじゃろ?と思って検索してみたら、同じ問題に行き当たって見事解決している方がいらっしゃいました。

http://bibo.jugem.jp/?eid=32

ターミナルで以下のように入力すればいいようです。

cd /var
sudo mkdir mysql
sudo ln -s /Applications/MAMP/tmp/mysql/mysql.sock /var/mysql/mysql.sock

ド文系の僕には理解不能でしたが、そのまま入力したところ、見事Warningが出なくなりました。


いまのところわかったのは、とりあえずここまで。
先に進んで、また何かわかったら書きます。