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