[CodeIgniter2.x]コマンドラインから使用してみた


ついに、CodeIgniter 2.0がリリースされました。PHP4対応を捨て、PHP5.1以上が必須らしいです。まだ、少ししか内部のソースを見ていないので何とも言えませんが、主要部分についてはそれほど大きな違いはなく、CodeIgniter 1.xの時の感覚にPHP5のプログラミングスタイルを適用すれば簡単に動かせます。

それで、今回新たにコマンドラインから使用できるようになったので、ちょっと試してみました。

広告

コントローラの作成

まずは、コマンドラインから呼び出すためのコントローラを作成します。

class Example_batch extends CI_Controller {
	public function __construct() {
		parent::__construct();
	}
 
	public function hoge($name) {
		echo "name={$name}\n";
	}
}

至って普通のコントローラですね。ただ、このままだとWEBからもアクセス出来てしまうので、下記のようにコマンドライン以外からのアクセスの場合にはエラーにする。などの対応が必要になります。

class Example_batch extends CI_Controller {
	public function __construct() {
		parent::__construct();
                // コマンドライン以外からのアクセスの場合、404エラー
		if (!$this->input->is_cli_request()) {
			show_404();
		}
	}
 
	public function hoge($name) {
		echo "name={$name}\n";
	}
}

実行

上記で作成したコントローラをコマンドラインから呼び出すには、下記のようになります。

$ php [CIディレクトリ]/index.php /example_batch/hoge/foo/
name=foo

index.php以降のパラメータがURIとして扱われます。

コマンドラインからのパラメータの解析自体はこんな感じでやっているみたいです。

system/core/URI.php#_parse_cli_args

private function _parse_cli_args()
{
	$args = array_slice($_SERVER['argv'], 1);
 
	return $args ? '/' . implode('/', $args) : '';
}

なので、以下のような実行方法も可能です。

$ php [CIディレクトリ]/index.php example_batch hoge foo
name=foo

ただ、index.php以降のパラメータをスラッシュ「/」で連結するので、query_stringなどを有効化した場合などを考慮すると前者の形式で渡した方が間違いが少ないと思います。

と、思ったのですが、現在はコマンドラインから実行する場合にquery_stringには対応していないみたいです。

最大実行時間

CodeIgniter 2では、下記のようにセーフモードではない場合に、PHPスクリプトの最大実行時間を指定しています。

system/core/CodeIgniter.php

/*
 * ------------------------------------------------------
 *  Set a liberal script execution time limit
 * ------------------------------------------------------
 */
	if (function_exists("set_time_limit") == TRUE AND @ini_get("safe_mode") == 0)
	{
		@set_time_limit(300);
	}

これは、上記で作成したバッチにも当てはまります。例えば、Example_batchコントローラに下記のような無限ループを行うメソッドを追加したとします。

public function while() {
	while (true) {
		echo "";
	}
}

で、これを実行すると300秒が経過した時にエラーとなります。

$ php index.php /example_batch/while/
PHP Fatal error:  Maximum execution time of 300 seconds exceeded in [CIディレクトリ]/application/controllers/example_batch.php on line 20

これを防ぐには、set_time_limitメソッドに0を指定すれば、無制限になるので、コンストラクタ内で実行します。

class Example_batch extends CI_Controller {
	public function __construct() {
		parent::__construct();
                // コマンドライン以外からのアクセスの場合、404エラー
		if (!$this->input->is_cli_request()) {
			show_404();
		}
		// 最大実行時間を無制限に設定
		if (function_exists("set_time_limit") == TRUE AND @ini_get("safe_mode") == 0) {
			@set_time_limit(0);
		}
	}
 
	public function hoge($name) {
		echo "name={$name}\n";
	}
 
	public function while() {
		while (true) {
			echo "";
		}
	}
}

手軽にコマンドラインから実行できるようになったので、modelやhelperをバッチ等で再利用しやすくなりましたね。

関連記事