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