この記事を三行にまとめると
Shellが動いてないことにある日気づいたCake2系ではファイルの場所が変わってた
どんまいどんまーい
なーんか最近、開発に関する記事ばっかり書いてるような気がするねぇ。もっとどーでもいいことをいっぱい書かないと、あかつきのお宿らしさが薄れていくような気がするんですが、まあそれはそれとして……。
CakePHPにはシェルを実行するための機能があります。これは、例えばクーロンの設定をしておいて、定期的に自動で処理を行ないたいようなメソッドを作っておくことができたりする、そんな機能です。
たいした話じゃないんですが、CakePHP1.3と2系ではシェルのファイルの置き場所とかがちょびっと変わってるので、バージョンアップした際にそのままにしとくと、動かないんですね。僕も随分長いこと放ったらかしてて、あるときふと見たら「あれ? 動いてねーな」ってなっちゃいました。
てなわけで、両者の違いをば。
sample.phpの中身は、こんな感じ。
このexecuteメソッドを実行する場合、人によって多少の違いはあるかもしれないですが、実行コマンドの書き方はおよそ以下のようになるかと思います。
ここでは『/var/www』の下にappフォルダとcakeフォルダが置いてあると仮定してます。
ざっくり説明すると、『/usr/bin/php』はPHPを実行するコマンド(で良いのかな?)、『/var/www/cake/console/cake.php』はシェルを起動するためのcake.phpファイルのパス、『sample』は実行するファイル名、『execute』は実行するメソッド名、『-app』は……そういえば、これは何だろうね? ちょっと分かんないや。パス。そんでもって『/var/www/app』はappフォルダのパス。
cake.phpっていうのはコアライブラリの中に最初からあるファイルでして、あまり中をちゃんと見たことはないけど、ShellDispatcherとかいうクラスが用意されてます。きっとこのクラスがシェルを実行するのでしょう。dispatcherだもんね。dispatchってどういう意味かよく知らないけど。
じゃあどこかっていうと、appフォルダの中に、1.3の頃にはなかった『Console』っていうディレクトリがあるんで、その中に置きます。直下ではなくて、その中にある『Command』っていうディレクトリの下。さっきと同じ要領でいくと『/Console/Command/SampleShell.php』になりますね。
ファイル名も1.3のときはsample.phpだったけど、2系はSampleShell.phpになります。まあこれは、コントローラーとかのファイルにつける命名規約と同じっすね。
ファイルの中は、1.3のときと同じで大丈夫。強いて言えば、App::uses()の記述が必要になりますかね。
で、これを実行する場合。
1.3のときとほとんど同じなんですけど、2系の場合はフォルダ名やファイル名の先頭は大文字になってますからね。そこは微妙に違いますね。あと実行するファイル名自体は『SampleShell』だけど、実行コマンドではShellの部分は省略して書くようです。省略しないと動かないのかどうかは……すみません、検証してないです。
些細な違いなので、修正するのは別に大変な作業ではないんですけどね。ほら、クーロンで毎日実行させてるやつとか、よっぽどコアな機能じゃないと、あまり確認しないじゃん? 垂れ流し状態じゃん? そんなことないっすか……そうですか。そうですよね。普通バージョンアップとかしたら、一通りテストとかしますもんね。
まあでも、たまにはこういうこともあるさ。人間だもの。
CakePHPにはシェルを実行するための機能があります。これは、例えばクーロンの設定をしておいて、定期的に自動で処理を行ないたいようなメソッドを作っておくことができたりする、そんな機能です。
たいした話じゃないんですが、CakePHP1.3と2系ではシェルのファイルの置き場所とかがちょびっと変わってるので、バージョンアップした際にそのままにしとくと、動かないんですね。僕も随分長いこと放ったらかしてて、あるときふと見たら「あれ? 動いてねーな」ってなっちゃいました。
てなわけで、両者の違いをば。
CakePHP1.3の頃
シェル用のファイルはvendorsっていうディレクトリの下に置いてました。vendorsの下にshellsというディレクトリがあって、その中にシェルファイルを作ると、そんな感じです。例えばsample.phpだったら『/vendors/shells/sample.php』ですね。sample.phpの中身は、こんな感じ。
class SampleShell extends Shell {
function execute() {
〜 処理を書く 〜
}
}
このexecuteメソッドを実行する場合、人によって多少の違いはあるかもしれないですが、実行コマンドの書き方はおよそ以下のようになるかと思います。
/usr/bin/php /var/www/cake/console/cake.php sample execute -app /var/www/app
ここでは『/var/www』の下にappフォルダとcakeフォルダが置いてあると仮定してます。
ざっくり説明すると、『/usr/bin/php』はPHPを実行するコマンド(で良いのかな?)、『/var/www/cake/console/cake.php』はシェルを起動するためのcake.phpファイルのパス、『sample』は実行するファイル名、『execute』は実行するメソッド名、『-app』は……そういえば、これは何だろうね? ちょっと分かんないや。パス。そんでもって『/var/www/app』はappフォルダのパス。
cake.phpっていうのはコアライブラリの中に最初からあるファイルでして、あまり中をちゃんと見たことはないけど、ShellDispatcherとかいうクラスが用意されてます。きっとこのクラスがシェルを実行するのでしょう。dispatcherだもんね。dispatchってどういう意味かよく知らないけど。
CakePHP2系になってから
まず、シェルのファイルを置く場所が変わりました。vendorsの下じゃなくなった。じゃあどこかっていうと、appフォルダの中に、1.3の頃にはなかった『Console』っていうディレクトリがあるんで、その中に置きます。直下ではなくて、その中にある『Command』っていうディレクトリの下。さっきと同じ要領でいくと『/Console/Command/SampleShell.php』になりますね。
ファイル名も1.3のときはsample.phpだったけど、2系はSampleShell.phpになります。まあこれは、コントローラーとかのファイルにつける命名規約と同じっすね。
ファイルの中は、1.3のときと同じで大丈夫。強いて言えば、App::uses()の記述が必要になりますかね。
App::uses('Shell', 'Console');
class SampleShell extends Shell {
function execute() {
〜 処理を書く 〜
}
}
で、これを実行する場合。
/usr/bin/php /var/www/Cake/Console/cake.php Sample execute -app /var/www/app
1.3のときとほとんど同じなんですけど、2系の場合はフォルダ名やファイル名の先頭は大文字になってますからね。そこは微妙に違いますね。あと実行するファイル名自体は『SampleShell』だけど、実行コマンドではShellの部分は省略して書くようです。省略しないと動かないのかどうかは……すみません、検証してないです。
些細な違いなので、修正するのは別に大変な作業ではないんですけどね。ほら、クーロンで毎日実行させてるやつとか、よっぽどコアな機能じゃないと、あまり確認しないじゃん? 垂れ流し状態じゃん? そんなことないっすか……そうですか。そうですよね。普通バージョンアップとかしたら、一通りテストとかしますもんね。
まあでも、たまにはこういうこともあるさ。人間だもの。