読者です 読者をやめる 読者になる 読者になる

CakePHP1.2のShellとTaskを使ってみる。

Cakeコマンドを自作できるらしいので、やってみた。
単純にバッチとかもそうだけど、テスト用のデータを作ったり、本番にアップしたり、いろんな用途に使えると思った。

まずはHelloWorld的な。

app/vendors/shells/test.php をつくる。

<?php

class TestShell extends Shell
{
    function main() {
        $this->out( "いらっしゃいませ" );
        $this->hr();
        $this->out( "ごちゅうもんをどうぞ" );
    }
}

?>

実行!
appのカレントディレクトリにいる場合

$ /home/htdocs/cake_installed/cake/console/cake test
Welcome to CakePHP v1.2.0.7296 RC2 Console
---------------------------------------------------------------
App : app
Path: /home/htdocs/cake_installed/app
---------------------------------------------------------------
いらっしゃいませ
---------------------------------------------------------------
ごちゅうもんをどうぞ
ポイント
  • Shellクラスを継承して作る。
  • ファイル名のキャメル記法(アッパーキャメルケース)+Shellがクラス名になる。
  • main()が実行される。
  • $this->out()で標準出力にだす。
  • $this->hr()でハイフンの連続、線をだす。


appにいない場合でも、実行するときにappのパスを教えてあげればOK。

$ /home/htdocs/cake_installed/cake/console/cake test -app /home/htdocs/cake_installed/app

ちなみに、appのほうじゃなくて、cake_installed/venders/shells/に配置したらappを分からせる必要はなし。

引数をもらう

コマンドライン引数は、$this->argsに入ってくる。

<?php

class TestShell extends Shell
{
    function main() {
        $this->out( join( $this->args ) );
    }
}

?>
$ /home/htdocs/cake_installed/cake/console/cake test hogehoge foo bar  -app /home/htdocs/cake_installed/app
Welcome to CakePHP v1.2.0.7296 RC2 Console
---------------------------------------------------------------
App : app
Path: /home/htdocs/cake_installed/app
---------------------------------------------------------------
hogehogefoobar

Welcome to CakePHPのメッセージを出さない

Shell::startupをオーバーライドしてあげる。

<?php

class TestShell extends Shell
{
    // オーバーライドして、Welcome to CakePHP・・・のメッセージを出さないようにする。
    function startup() {}
    
    function main() {
        $this->out( "いらっしゃいませ" );
        $this->hr();
        $this->out( "ごちゅうもんをどうぞ" );
    }
}

?>

サブ的な処理を作って実行。

<?php

class TestShell extends Shell
{
    // オーバーライドして、Welcome to CakePHP・・・のメッセージを出さないようにする。
    function startup() {}
    
    function main() {
        $this->out( "いらっしゃいませ" );
        $this->hr();
        $this->out( "ごちゅうもんをどうぞ" );
    }

    function thanks() {
        $this->out ( "ありがとうございましたー" );
    }
}

?>

呼び出してみる。

$ /home/htdocs/cake_installed/cake/console/cake test thanks -app /home/htdocs/cake_installed/app
ありがとうございましたー

Taskを作る。

app/vendors/shells/tasks/input.php をつくる。

<?php
class InputTask extends Shell {

    function execute() {
        $this->out( join( $this->args ) );
    }
}
?>


app/vendors/shells/test.phpを編集。

<?php

class TestShell extends Shell
{
    var $tasks = array( 'Input' );

    // オーバーライドして、Welcome to CakePHP・・・のメッセージを出さないようにする。
    function startup() {}

    function main() {
        $this->out( "いらっしゃいませ" );
        $this->hr();
        $this->out( "ごちゅうもんをどうぞ" ); 
    }

}
?>

呼び出してみる。

$ /home/htdocs/cake_installed/cake/console/cake test input a i u e o -app /home/htdocs/cake_installed/app
aiueo
ポイント
  • Shellクラスを継承する。
  • ファイル名のキャメル記法(アッパーキャメルケース)+Taskがクラス名になる。
  • execute()が実行される。
  • 呼び出す側のShellには$var $tasksに登録しておく。
  • コマンドラインからは、『cake シェル タスク [パラメータ] 』で実行


いろんなShellから呼び出すようになる処理をTaskとしておくと良いのかも。


bakeみたいに対話形式のコマンドを簡単に作る。

選択肢をつくって、必ずその中から選ばせるようにできる。

<?php

class TestShell extends Shell
{
    // オーバーライドして、Welcome to CakePHP・・・のメッセージを出さないようにする。
    function startup() {}

    function main() {
        $this->out( "いらっしゃいませ" );
        $this->hr();
        $this->out( "ごちゅうもんをどうぞ" );
        $this->hr();
        $value = $this->in( "なにがいいですか?", array( "rerere", "ohoho", "ufufu" ), "ohoho" );
        $this->hr();
        $this->out( $value . "ですねーわかりましたー" );
    }
}
?>
$ /home/htdocs/cake_installed/cake/console/cake test -app /home/htdocs/cake_installed/app
いらっしゃいませ
---------------------------------------------------------------
ごちゅうもんをどうぞ
---------------------------------------------------------------
なにがいいですか? (rerere/ohoho/ufufu)
[ohoho] > fugafuga
なにがいいですか? (rerere/ohoho/ufufu)
[ohoho] > rerere
---------------------------------------------------------------
rerereですねーわかりましたー
ポイント
  • Shell::in($prompt, $options = null, $default = null)
    • 第一引数がプロンプトに出すメッセージ。これだけ必須。
    • 第二引数が選択肢
    • 第三引数がエンター押したときに指定されるデフォルト。
    • 入力された値が戻り値として返される。

標準エラーに出力する。

<?php

class TestShell extends Shell
{
    // オーバーライドして、Welcome to CakePHP・・・のメッセージを出さないようにする。
    function startup() {}

    function main() {
        $this->err( "標準エラーにだしてみた" );
        $this->out( "標準出力にだしてみた。");
        $this->error( "エラー番号123", "内容はこれこれこうです。" );
    }
}
?>
$ /home/htdocs/cake_installed/cake/console/cake test -app /home/htdocs/cake_installed/app 2>err.txt
標準出力にだしてみた。

$ cat err.txt
Error: 標準エラーにだしてみた
Error: エラー番号123
内容はこれこれこうです。
ポイント
  • Shell::err()とShell::error()の二つの方法があるみたい。


こちらで勉強させていただきました。

2008/08/05追記

  • Shell::createFile($path, $contents)を使えば、ファイルが作れることがわかった。(y/n/q)の確認つきで。
  • 上の確認が要らない場合、Shell::interactiveをfalseにすればオッケー。
<?php
function main() {
    $this->interactive = false;
    $this->createFile( tempnam( "/home/htdocs/cake_installed/app/tmp/", "prefix_" ), "ファイルの内容をStringで" );

}