we moved here http://radzserg.com/2012/04/07/run-zend-cli-scripts-yii-style/
yii has a nice yiic tool - cli for *nix so you can run scripts in this way
./yiic mynicescript --param1=2 --param2=2
this is really cool feature is essentially just a bootstrap for for running cli yii scripts(commands).
It's weird that Zend Framework(ZF) doesn't have something similar. I propose you my variant for ZF
There are 2 classes (btw some features are similar with Extended Yii CConsoleCommand :):
<?php /** * * Implements function to work from CLI * @author radzserg * */ abstract class App_Script_Abstract { const VERBOSE_ERROR = 'error'; const VERBOSE_INFO = 'info'; protected $_verbose; /** * * Return class name * @return string */ public function getName() { return get_class($this); } /** * Get params from cli * myscript.php --param1=value --param2=value * @return array */ public function getCliParams() { $params = isset($_SERVER['argv']) ? $_SERVER['argv'] : array(); $resultParams = array(); foreach ($params as $paramPair) { if (strpos($paramPair, '--') !== false && strpos($paramPair, '--') == 0) { $count = 1; $paramPair = str_replace('--', '', $paramPair, $count); $paramPair = explode('=', $paramPair, 2); $key = isset($paramPair[0]) ? $paramPair[0] : null; $value = isset($paramPair[1]) ? $paramPair[1] : ''; if ($key) { $resultParams[$key] = $value; } } } return $resultParams; } /** * Verbose info * @param $message * @param null $type */ public function verbose($message, $type = null) { if ($this->_verbose === NULL) { $cliParams = $this->getCliParams(); $this->_verbose = isset($cliParams['verbose']) ? true : false; } if ($this->_verbose) { if ($type == self::VERBOSE_ERROR) { // message in red echo date('H:i:s ') . "\033[31;1m" . $message . "\033[0m\n"; } elseif ($type == self::VERBOSE_INFO) { // message in green echo date('H:i:s ') . "\033[32;1m" . $message . "\033[0m\n"; } else { echo date('H:i:s ') . $message . "\n"; } } } }
<?php class App_Script_ScriptRunner extends App_Script_Abstract { /** * * Run script */ public function run() { $script = $this->_getScriptObject(); $params = $this->getCliParams(); if (isset($params['help'])) { $script->help(); } else { $script->execute($params); } } /** * * Return script nam that have to be run * Mandatory format * * cron_runner.php scriptName [--param1=value --param2=value] * @return string */ public function getScriptName() { return isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : NULL; } /** * * Return script object instance of App_Exception_System * @return App_Script_Abstract * @throws App_Exception_System */ protected function _getScriptObject() { $scriptName = $this->getScriptName(); if (!$scriptName) { throw new App_Exception_System("Cron name is not defined. Server argv " . print_r($_SERVER['argv'], true)); } $scriptName = "App_Script_Command_" . ucfirst($scriptName); $script = new $scriptName; return $script; } }Second class App_Script_ScriptRunner is a descendant class and you can extend it as you want. As you see in my example I extended _getScriptObject my scrips are in /App/Script/Command perhaps just /scripts is better place. For example I use another one App_Script_CronRunner to run cron scripts that additionally adds some stat about script execution.
And finally you have to add entry script for CLI. I put it in /scripts folder.
/** * Run CLI scripts * * php cron_runner.php myCommandName --param1=value --param2=value * command should be located in App/Script/Command/ */ $envention = file_get_contents(dirname(__FILE__) . '/cli_envention'); if (!$envention) { throw new Exception("CLI envention is not defined"); } define('APPLICATION_ENV', $envention); define('ROOT_PATH', realpath(dirname(__FILE__) . '/..')); define('APPLICATION_PATH', ROOT_PATH . '/application'); set_include_path(implode(PATH_SEPARATOR, array( realpath(ROOT_PATH . '/library'), get_include_path(), ))); if ('development' == APPLICATION_ENV) { error_reporting(E_ALL | E_NOTICE); ini_set('display_errors', 1); } require_once 'App/Application/Console.php'; // Create application, bootstrap, and run $application = new App_Application_Console( APPLICATION_ENV, APPLICATION_PATH . '/configs/application.ini' ); $application->bootstrap(); $scriptRunner = new App_Script_ScriptRunner(); $scriptRunner->run();
As you see it's very similar to index.php The last hack that I use here is App_Application_Console it's full copy of Zend_Application but uses his own Bootstrap class.
That's it now you can run your scripts in this way.
cd /scripts
php script_runner.php haveFun --param1=123 --verbose
This is pretty useful script, It really helpful for me while coding on zend framework.
ReplyDeletePHP Zend Development | Offshore PHP Developers