When I first started working with the Interfaces team at Rubicon, we were primarily a front end oriented team. As such, we didn’t have too many scripts that needed to be run from the command line. The few we had weren’t well organized.
As the team and code base grew, we began accumulating more and more adjunct scripts that really didn’t have a clear home in our code base. Plus, new scripts required many of the libraries that we used in our front-end framework—and those needed to be bootstrapped in every file. Things were becoming unwieldy, so I decided to clean it all up.
Rubicon leverages the Zend Framework along with its MVC system for our web front end, so I decided it was only natural to apply this pattern to our CLI scripts as well.
My first step was to determine how to run a script. A call to the script should be akin to a request with a specified controller, action, and optional parameters. The natural command was something like this:
$ php run.php -c myController -a myAction -p 'key1=val1&key2=val2&key3=val3'
This allowed us to use most of the Zend Framework bootstrapping process, with run.php the equivalent of the index.php in a traditional web based setup.
In addition to the request structure, I also wanted to keep the controller API as similar as possible, ideally with all the same request and view helpers available. I created a few new classes for the bootstrapping process in order to achieve this.
Sangria_Application_Bootstrap_Cli— grabs the command line arguments and assigns them like request params
Sangria_Controller_Request_Cli— sets controller, action, and parameters
Sangria_Controller_Router_Cli— zend needs some router, even if it doesn’t do anything, basically disables built in routing to be overridden with the command line parameters
Sangria_Application_Resource_Cli_Frontcontroller(optional) — simply disables exceptions, this could probably be ignored, or at least moved somewhere else.
Sangria_Application_Resource_Cli— mainly does internal stuff, probably not needed to be included in the post, bootstraps a user, ect.
My run.php file looks like:
#!/usr/bin/php -q setFallbackAutoloader(true); // Create application, bootstrap, and run $application = new Zend_Application( APPLICATION_ENVIRONMENT, array( 'bootstrap' => array( 'path' => 'Sangria/Application/Bootstrap/Cli.php', 'class' => 'Sangria_Application_Bootstrap_Cli' ), 'autoloaderNamespaces' => array( 'Sangria_', 'Zend_' ), 'pluginPaths' => array( 'Sangria_Application_Resource_Cli' => 'Sangria/Application/Resource/Cli', 'Sangria_Application_Resource' => 'Sangria/Application/Resource' ), 'resources' => array( 'session' => array(), 'cli' => array(), 'frontcontroller' => array( 'controllerDirectory' => APPLICATION_PATH.'/c', 'plugins' =>array() ) ) ) ); $application->bootstrap()->run();
The Zend Framework bootstraps the same as it would in a web request. It calls the appropriate controller and action, and allows access to all parameters passed to the script the same way we access them from a standard request via
$this->_getParam('key'); I also bootstrapped a view object in case any of my library functions are using it to generate an email template or something.
Finally, I created a base Controller class to disable the layout and page rendering:
And there you have it! Zend Framework in ur terminal MVCing ur cli scriptz.Tags: cli, mvc, php, zend