murave

CakePHP でシェルを書くときに最初にやったこと(親クラス作り)

CakePHP にはデバッグで便利な pr() って関数があります。
出力の前後に pre タグ を付けてくれる print_r() のラッパーです。当然Web用。

シェルにも欲しいです。てなわけで作りました。

function pr($obj){
$pr = print_r($obj, true);
$this->out($pr);
}

簡単。こんな感じで使います。

$popopopooon = array('こんにちわ' => 'こんにちワン', 'ありがとう' => 'ありがとウサギ');
$this->pr($popopopooon);

このようにコンソールに出力されます。

Array
(
[こんにちわ] => こんにちワン
[ありがとう] => ありがとウサギ
)

print_r() は第2引数に true を渡すと出力せずに結果を返してくれるのでオブジェクト構造をログに出したりするときにも便利です。
 
でもコレ、全部のシェルに書きたくない。

どこに集約したらいいのか悩んだのですが、実際に実行するシェルの親クラスを作成して継承することにしました。継承の段数が増えるのはあまりすきじゃないのですが、Shellクラス をそのまま継承するよりも1段増やしといたほうがいいかな?って気もしたので。

appbase.php

class AppbaseShell extends Shell {

function initialize() {
parent::initialize();
}

function startup() {
//ウェルカムメッセージを消すためにオーバーライド
}

/**
* デバッグ用
*/
protected function pr($obj){
$pr = print_r($obj, true);
$this->out($pr);
}
}

ついでに startup() をオーバライドしてウェルカムメッセージを消しました。
こういう事やるには1段あいだに入ってるほうがいいですね。

実際に起動するシェルは AppbaseShellクラス を継承します。

aisatu.php

App::import('Shell', 'Appbase');
class AisatuShell extends AppbaseShell {
function initialize() {
parent::initialize();
}

function main() {
$popopopooon = array('こんにちわ' => 'こんにちワン', 'ありがとう' => 'ありがとウサギ');
$this->pr($popopopooon);
}
}

サンプルコードは今テキトーに書いたのでちょっとあやしいかも。

最後にオチを。

このprメソッド、実際に作ったんですが普通に print_r() すればコンソールに出力されるんですよねー。「そりゃそうだ」と後で気づいたわけで。

CakePHP のシェルでは $this->out() でコンソールへの出力をすることになってますが、開発中にしか使わないし print_r() をそのまま使えばいいかなと。親クラスは機能の集約に役立ってます。