I would like to run a Zend Framework action to generate some files, from command line. Is this possible and how much change would I need to make to my existing Web project t
akond's solution above is on the best track, but there are some subtleties that may may his script not work in your environment. Consider these tweaks to his answer:
Bootstrap.php
protected function _initRouter()
{
if( PHP_SAPI == 'cli' )
{
$this->bootstrap( 'FrontController' );
$front = $this->getResource( 'FrontController' );
$front->setParam('disableOutputBuffering', true);
$front->setRouter( new Application_Router_Cli() );
$front->setRequest( new Zend_Controller_Request_Simple() );
}
}
Init error would probably barf as written above, the error handler is probably not yet instantiated unless you've changed the default config.
protected function _initError ()
{
$this->bootstrap( 'FrontController' );
$front = $this->getResource( 'FrontController' );
$front->registerPlugin( new Zend_Controller_Plugin_ErrorHandler() );
$error = $front->getPlugin ('Zend_Controller_Plugin_ErrorHandler');
$error->setErrorHandlerController('index');
if (PHP_SAPI == 'cli')
{
$error->setErrorHandlerController ('error');
$error->setErrorHandlerAction ('cli');
}
}
You probably, also, want to munge more than one parameter from the command line, here's a basic example:
class Application_Router_Cli extends Zend_Controller_Router_Abstract
{
public function route (Zend_Controller_Request_Abstract $dispatcher)
{
$getopt = new Zend_Console_Getopt (array ());
$arguments = $getopt->getRemainingArgs();
if ($arguments)
{
$command = array_shift( $arguments );
$action = array_shift( $arguments );
if(!preg_match ('~\W~', $command) )
{
$dispatcher->setControllerName( $command );
$dispatcher->setActionName( $action );
$dispatcher->setParams( $arguments );
return $dispatcher;
}
echo "Invalid command.\n", exit;
}
echo "No command given.\n", exit;
}
public function assemble ($userParams, $name = null, $reset = false, $encode = true)
{
echo "Not implemented\n", exit;
}
}
Lastly, in your controller, the action that you invoke make use of the params that were orphaned by the removal of the controller and action by the CLI router:
public function echoAction()
{
// disable rendering as required
$database_name = $this->getRequest()->getParam(0);
$udata = array();
if( ($udata = $this->getRequest()->getParam( 1 )) )
$udata = explode( ",", $udata );
echo $database_name;
var_dump( $udata );
}
You could then invoke your CLI command with:
php index.php Controller Action ....
For example, as above:
php index.php Controller echo database123 this,becomes,an,array
You'll want to implement a more robust filtering/escaping, but, it's a quick building block. Hope this helps!
Just saw this one get tagged in my CP. If you stumbled onto this post and are using ZF2, it's gotten MUCH easier. Just edit your module.config.php's routes like so:
/**
* Router
*/
'router' => array(
'routes' => array(
// .. these are your normal web routes, look further down
),
),
/**
* Console Routes
*/
'console' => array(
'router' => array(
'routes' => array(
/* Sample Route */
'do-cli' => array(
'options' => array(
'route' => 'do cli',
'defaults' => array(
'controller' => 'Application\Controller\Index',
'action' => 'do-cli',
),
),
),
),
),
),
Using the config above, you would define doCliAction in your IndexController.php under your Application module. Running it is cake, from the command line:
php index.php do cli
Done! Way smoother.
You can use wget command if your OS is Linux. For example:
wget http://example.com/controller/action
See http://linux.about.com/od/commands/l/blcmdl1_wget.htm
UPDATE:
You could write a simple bash script like this:
if wget http://example.com/controller/action
echo "Hello World!" > /home/wasdownloaded.txt
else
"crap, wget timed out, let's remove the file."
rm /home/wasdownloaded.txt
fi
Then you can do in PHP:
if (true === file_exists('/home/wasdownloaded.txt') {
// to check that the
}
Hope this helps.
akond idea works great, except the error exception isnt rendered by the error controller.
public function cliAction() {
$this->_helper->layout->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);
foreach ($this->_getParam('error_handler') as $error) {
if ($error instanceof Exception) {
print "cli-error: " . $error->getMessage() . "\n";
}
}
}
and In Application_Router_Cli, comment off the echo and die statement
public function assemble($userParams, $name = null, $reset = false, $encode = true) {
//echo "Not implemented\n";
}
I have used wget command
wget http://example.com/module/controller/action -O /dev/null
-O /dev/null
if you dont want to save the output
You can just use PHP as you would normally from the command line. If you call a script from PHP and either set the action in your script you can then run whatever you want.
It would be quite simple really. Its not really the intended usage, however this is how it could work if you wanted to.
For example
php script.php
Read here: http://php.net/manual/en/features.commandline.php