php Zend Framework で構築されたアプリケーションで、定期的に Cron から実行される処理をフレームワークの一部として実装した時のメモ。
手順としては、 php コマンドラインで呼び出した際のオプションを取得し、コントローラ、アクション、モジュール、パラメータを適切に設定してリクエストを構築、ルーター、レスポンスを指定してフロントコントローラを実行する。
まず、ほぼ空っぽのルータークラスを作成する。 CLI から呼び出される場合はルーティングを設定する必要がない事が前提。とりあえずこんな感じ。
<?php class Zext_Controller_Router_Cli extends Zend_Controller_Router_Abstract implements Zend_Controller_Router_Interface { public function assemble($userParams, $name = null, $reset = false, $encode = true) {} public function route(Zend_Controller_Request_Abstract $dispatcher) {} } ?>
* クラス名は好み。俺はフレームワークの抽象クラスを継承する場合は Zend の代わりに Zext(Zend extenstion まぎらわしい) て頭に付けてる。
次にコマンドライン引数を処理して、コントローラ名、アクション名、パラメータを取得する。
ここからの処理は全て bootstrap に実装される前提。別に FrontControler が呼ばれる前ならどこでもいい。
CLI にまるめて渡されるパラメータは以下を想定する。
--zfc=controller_name or -c コントローラ名 --zfa=action_name or -a アクション名 --zfp=param1:value1,param2:value2,... or -p パラメータ
Zend_Console_Getopt を使用してこれらのパラメータを取得する。
ついでに取得したパラメータを使って、リクエストオブジェクトの生成まで。
$opts = new Zend_Console_Getopt(array( 'zfc|c=s' => 'controller', 'zfa|a=s' => 'action', 'zfp|p=s' => 'parameters', )); $opts->parse(); if( isset($opts->zfc) ) { $zfps = split(',', $opts->zfp); $params = array(); foreach( $zfps as $z ) { list($name, $value) = split(':', $z); $params[$name] = $value; } echo 'Controller: ' . $opts->zfc . "\n"; echo 'Action: ' . $opts->zfa . "\n"; echo "Parameters: \n"; var_dump($params); // create request object $request = new Zend_Controller_Request_Simple($opts->zfa, $opts->zfc, NULL, $params); }
最後にフロントコントローラを設定して、やる。
if( isset($request) ) { $frontController = Zend_Controller_Front::getInstance(); require_once('application/Zext/Controller/Router/Cli.php'); $frontController->setRequest($request); $frontController->setRouter(new Zext_Controller_Router_Cli()); $frontController->setResponse(new Zend_Controller_Response_Cli()); unset($frontController); }
最後にこれが CLI から正しく実行できるかを確認してみる。
$ php index.php --zfc=index --zfa=index --zfp="p1:hello,p2:world"
Using Zend Framework from the Command Line