コンソールアプリケーション

コンソールアプリケーションは、主として、オンラインのウェブアプリケーションが必要とするオフラインの仕事、例えば、コード生成、検索用インデックスのコンパイル、メール送信等を実行するために使用されます。 Yii はオブジェクト指向でコンソールアプリケーションを書くためのフレームワークを提供しています。 このフレームワークを使うと、オンラインのウェブアプリケーションが使用するリソース (例えばデータベース接続) にコンソールアプリケーションからアクセスすることが可能になります。

概要

Yii におけるコンソールのタスクは コマンド(command) という形で提供されます。 すなわち、コンソールのコマンドは CConsoleCommand を継承したクラスとして書かれます。

yiic webapp ツールを使って Yii の初期スケルトンアプリケーションを作成するとき、protected ディレクトリの下に二つのファイルが有ることに気付くでしょう。

コンソールウィンドウで次のようにコマンドを入力してみましょう。

cd protected
yiic help

上記を実行すると、利用できるコンソールコマンドの一覧が表示されます。 デフォルトでは、利用可能なコマンドには、Yii フレームワークによって提供されるもの (システムコマンド と呼ばれます) と、それぞれのアプリケーションのためにユーザが開発したもの (ユーザコマンド と呼ばれます) が含まれます。

コマンドの使い方を見るためには、以下のように実行します。

yiic help <コマンド名>

そして、コマンドを実行するためには、以下のコマンド書式を使います。

yiic <コマンド名> [引数...]

コマンドを作成する

コンソールコマンドは CConsoleApplication::commandPath によって定義されるディレクトリの下にクラスファイルとして保存されます。 既定値では、このディレクトリは protected/commands です。

コンソールコマンドのクラスは CConsoleCommand を継承しなければなりません。 また、クラス名は XyzCommand の形式でなければなりません。 ここで Xyz は、コマンド名の最初の文字を大文字にしたものを指します。 例えば、sitemap というコマンドは、SitemapCommand というクラス名を使わなければなりません。 コンソールコマンドの名前は大文字と小文字を区別します。

Tip: CConsoleApplication::commandMap を構成すれば、別の命名規約によるコマンドクラスを作成したり、別のディレクトリに保存したりすることも出来ます。

新しいコマンドを作成する場合、通常は CConsoleCommand::run() をオーバーライドしたり、一つないし複数のコマンドアクションを開発する必要があります (次の章で説明します)。

コンソールコマンドを実行する時は、その CConsoleCommand::run() メソッドがコンソールアプリケーションから呼び出されます。 コンソールコマンドのすべての引数も、下記のメソッドシグニチャに従って CConsoleCommand::run() に引き渡されます。

public function run($args) { ... }

ここで $args が、コマンドラインで指定された追加の引数を示しています。

コンソールコマンドの中では、Yii::app() を使ってコンソールアプリケーションのインスタンスにアクセスすることが出来ます。 そして、それを通じて、データベース接続などのリソースにアクセスすることが出来ます (例えば、Yii::app()->db)。 お分かりだと思いますが、Yii::app() の使い方は、ウェブアプリケーションで出来ることと非常によく似たものです。

情報: バージョン 1.1.1 以降は、同一マシンの すべての Yii アプリケーションによって共有できるグローバルなコマンドを作成することも出来ます。 そうするためには、YII_CONSOLE_COMMANDS という名前の環境変数を定義して、実際に存在するディレクトリを指し示すようにして下さい。 そうすれば、グローバルなコマンドのクラスファイルをこのディレクトリに配置することが出来ます。

コンソールコマンドアクション

注意: コンソールコマンドアクションの機能は、バージョン 1.1.5 以降で利用することが出来ます。

コンソールコマンドは、しばしば、異なるコマンドライン引数 (必須のものもあれば、任意のものもある) を取り扱う必要があります。 また、異なるサブタスクを扱うためにいくつかのサブコマンドを提供しなければならない場合もあります。 これらの仕事は、コンソールコマンドアクションを使って、単純化することが出来ます。

コンソールコマンドアクションはコンソールコマンドクラスのメソッドです。 そのメソッドの名前は、actionXyz の形式でなければなりません。 ここで Xyz は先頭を大文字にしたアクション名を指します。 例えば、actionIndex というメソッドは、index という名前のアクションを定義するものです。

特定のアクションを実行するためには、以下のコンソールコマンド書式を使います。

yiic <コマンド名> <アクション名> --option1=value1 --option2=value2 ...

追加される option-value のペアは、アクションメソッドに名前付きの引数として渡されます。 すなわち、xyz というオプションの値が $xyz という引数としてアクションメソッドに引き渡されます。 例として、以下のようなコマンドクラスを定義したとしましょう。

class SitemapCommand extends CConsoleCommand
{
    public function actionIndex($type, $limit=5) { ... }
    public function actionInit() { ... }
}

このとき、次のコンソールコマンドはすべて actionIndex('News', 5) の呼び出しに帰結します。

yiic sitemap index --type=News --limit=5

// $limit はデフォルト値を取る
yiic sitemap index --type=News

// $limit はデフォルト値を取る
// 'index' はデフォルトアクションなので、アクション名を省略することが出来る
yiic sitemap --type=News

// オプションの順序は問題にならない
yiic sitemap index --limit=5 --type=News

オプションが値を指定せずに与えられた場合 (例えば、--type=News のかわりに --type) は、対応するアクションの引数は、boolean で true であると見なされます。

注意: たとえば --type News-t News のような、別のオプション形式はサポートされていません。

引数は、配列型のヒントをつけて宣言することによって、配列値を取ることが出来ます。

public function actionIndex(array $types) { ... }

配列値を与えるためには、コマンドラインで必要なだけ同じオプションを繰り返します。

yiic sitemap index --types=News --types=Article

上記のコマンドは、最終的に actionIndex(array('News', 'Article')) を呼び出すことになります。

バージョン 1.1.6 以降、Yii は無名のアクション引数とグローバルオプションの使用もサポートするようになりました。 例えば、yiic sitemap index --limit=5 News というコマンドでは、名前付きの引数である limit が 5 という値を取っているのに対して、News という無名の引数が指定されています。

無名の引数を使用するためには、コマンドアクションは $args という名前の引数を宣言しなければなりません。 例えば、

public function actionIndex($limit=10, $args=array()) {...}

この $args 配列が全ての無名引数の値を保持します。

グローバルオプションは、コマンドに属する全てのアクションによって共有されるコマンドラインオプションを意味します。 例えば、いくつかのアクションを提供するコマンドにおいて、どのアクションにおいても verbose という名前のオプションを使いたい場合があります。 すべてのアクションメソッドで $verbose という引数を宣言することも出来ますが、もっと良い方法は、それをコマンドクラスの パブリックメンバ変数 として宣言して、verbose をグローバルオプションにすることです。

class SitemapCommand extends CConsoleCommand
{
    public $verbose=false;
    public function actionIndex($type) {...}
}

上記のコードによって、verbose オプションを付けてコマンドを実行することが可能になります。

yiic sitemap index --verbose=1 --type=News

終了コード

注意: コンソールコマンドで終了コードを返すことは、バージョン 1.1.11 以降で可能になっています。

クロンジョブまたは継続的インテグレーションサーバ (CIサーバ) を通じてコンソールコマンドを自動的に走らせる場合は、コマンドが正常終了したか、それともエラーが発生したかが、いつでも関心事になります。 これは、プロセスが終了時に返す終了コードをチェックすることで知ることが出来ます。

終了コードは、0 から 254 までの整数値です (php マニュアル exit 参照)。 正常終了時には 0 を返し、0 より大きい全ての値はエラーを示すものとします。

コンソールコマンドのアクションメソッドまたは run() メソッドの中で整数値を返すと、終了コードを指定してアプリケーションを終了することが出来ます。 例えば、

if (/* error */) {
    return 1; // エラーコード 1 で終了
}
// ... do something ...
return 0; // 正常終了

返り値が無い場合は、アプリケーションは終了コード 0 で終了します。

コンソールアプリケーションをカスタマイズする

デフォルトでは、アプリケーションが yiic webapp ツールで作成された場合、コンソールアプリケーションの構成ファイルは protected/config/console.php になります。 ウェブアプリケーションの構成ファイルと同じように、このファイルは、コンソールアプリケーションのインスタンスのプロパティ初期値を表す配列を返す PHP スクリプトです。 その結果、CConsoleApplication のすべてのパブリックプロパティは、このファイルによって構成することが出来ます。

コンソールコマンドはウェブアプリケーションの必要を満たすために作られることがよくありますので、ウェブアプリケーションによって使用されるリソース (DB 接続など) にアクセスする必要があります。 そうするためには、コンソールアプリケーションの構成ファイルで、以下のように記述します。

return array(
    ......
    'components'=>array(
        'db'=>array(
            ......
        ),
    ),
);

ごらんのように、構成の形式はウェブアプリケーションの構成でする場合と非常によく似たものです。 これは、CConsoleApplicationCWebApplication が共通の基本クラスを持っているためです。

$Id$