Zend Framework 2 : Step by Step Create Console Application
Sometimes, console is more interactive than GUI, and quicker to be executed. Console Application often need by cron job or generator for your datawarehouse that summarize your transactional data. It’s very easy in Zend Framework 2.
Just define console route, register controller invokables, set help for command line ( if necessary ), and run it.
Before we doing anything, if we run :
php index.php
and the console will show the following :
In this post, I will show you an example to show how to get current processes of your server by rule :
Firstly, set the module.config.php
return array( 'controllers' => array( 'invokables' => array( 'MyModule\Controller\Do' => 'MyModule\Controller\DoController', ) ), 'console' => array( 'router' => array( 'routes' => array( 'get-happen-use' => array( 'options' => array( // add [ and ] if optional ( ex : [<doname>] ) 'route' => 'get happen [--verbose|-v] <doname>', 'defaults' => array( '__NAMESPACE__' => 'MyModule\Controller', 'controller' => 'do', 'action' => 'donow' ), ), ), ) ) ), );
So, the Controller code may be like this :
namespace MyModule\Controller; use Zend\Mvc\Controller\AbstractActionController, Zend\Console\Request as ConsoleRequest; class DoController extends AbstractActionController { public function donowAction() { $request = $this->getRequest(); // Make sure that we are running in a console and the user has not tricked our // application into running this action from a public web server. if (!$request instanceof ConsoleRequest){ throw new \RuntimeException('You can only use this action from a console!'); } // Get system service name from console and check if the user used --verbose or -v flag $doname = $request->getParam('doname', false); $verbose = $request->getParam('verbose'); $shell = "ps aux"; if ($doname){ $shell .= " |grep -i $doname "; } $shell .= " > /Users/abdulmalikikhsan/www/success.txt "; //execute... system($shell, $val); if(!$verbose){ echo "Process listed in /Users/abdulmalikikhsan/www/success.txt \r\n"; }else{ $file = fopen('/Users/abdulmalikikhsan/www/success.txt',"r"); while(! feof($file)){ $listprocess = trim( fgets($file) ); echo $listprocess."\r\n"; } fclose($file); } } }
And if we run :
php index.php get happen --verbose apache2
we will get the result :
NB :
For Console usage help, add the following in Module class :
namespace MyModule; use Zend\ModuleManager\Feature\AutoloaderProviderInterface, Zend\ModuleManager\Feature\ConfigProviderInterface, Zend\ModuleManager\Feature\ConsoleUsageProviderInterface, Zend\Console\Adapter\AdapterInterface as Console; class Module implements AutoloaderProviderInterface, ConfigProviderInterface, ConsoleUsageProviderInterface { public function getAutoloaderConfig(){ /* common code*/ } public function getConfig(){ /* common code */} public function getConsoleUsage(Console $console) { return array( // Describe available commands 'get happen [--verbose|-v] <doname>' => 'Get Process already happen', // Describe expected parameters array( 'doname', 'Process Name' ), array( '--verbose|-v', '(optional) turn on verbose mode' ), ); } }
Done !
References :
1. http://zf2.readthedocs.org/en/latest/modules/zend.console.introduction.html
[…] https://samsonasik.wordpress.com/2012/09/05/zend-framework-2-step-by-step-create-console-application/ […]
Thank you. But you have some mistake.
If use it with -v, not with –verbose, than your example not work.
You forgot add this
$verbose = $request->getParam(‘verbose’);
if (!$verbose) {
$verbose = $request->getParam(‘v’);
}
Check all parameter types.
I appreciate your report.
What is not clear to me, is the code of the “index.php”, and where
is located so that it can function properly.
You could include the code and its location
thanks
folder public. look at the docs : http://zf2.readthedocs.org/en/latest/modules/zend.console.routes.html
Thank you very much,
I appreciate your response, very good articles on your blog
regards
You’re welcome
Asking myself how to handle these workflows if your application works with authentication like zfc-user and bjyAuthorize.
If i call “index.php do something”, he’s tellin me “route with name zfcuser/login not found!”.
Any ideas?
look at the module.config.php , route should be under console key.
Hi Samsonasik.
I want to have both the module and the console application in the same code module. It’s possible.?
Or I have to create one for web and one for code code for console.?
Thank you.
possible, modify the if not console request 🙂
Hi Samsonasik,
I need to know that how can i access db with console. When i try to fetch a row of a table through a model i get error.
Zend/Db/Adapter/Execption/RuntimeException –> Connect error could not find driver.
I’m Using PDO as a driver.
if service is not registered, then you need to re-register service, read this http://blog.evan.pro/introduction-to-the-zend-framework-2-servicemanager .
May be i was not to clear about my problem or you may have understood it. My problem is that when i access the controller->action from browser i don’t get any error such as service not found. But when i access it through console than i get error Zend/Db/Adapter/Execption/RuntimeException –> Connect error could not find driver. I hope now i’m more clear about my problem. As the service is located in config/autoload/database.local.php.
I’m following akrabat tutorial and so through url/browser i don’t get any error.
But on the other hand when i write this in my controller->action
$dbAdapter = $this->serviceLocator->get(‘Zend\Db\Adapter\Adapter’); i get no error and i’m able to execute queries as i wish.
Thanks in advance.
please follow the latest docs : http:/zf2.readthedocs.org
Hi Samsonasik,
I followed your tutorial. I have done every step including routes. But I am unable to run the script from command line. Every time I run my script from command line it shows nothing on console (no output and no error either)
I am new on this. I am not sure if the zend framework/console library should be added on composer or not. If it should be added in the composer, please send me the link of console for compoer.
Thanks a lot.
Make sure you have set error_reporting to E_ALL or E_ERROR .
Pretty simple and just working. Great!
Thank you. This post helped me alot
Please suggest me how can I create ACL in zend 2
Hi,
When i run this on cmd it shows an error:
‘ps’ is not recognized as an internal or external command,
operable program or batch file.
you probably run in windows. in summary, it’s just an example, you can use for specific task in your specific os with other command.
Thanks samsonasik.
Hi samsonasik,
I see that you register the controller as invokable.
does this mean that the controller is also accessible with a normal HTTP request if i have a normal route with the patterns matching the console route?
registering in invokables is not related with accessed with HTTP request or not. for your question, there is AbstractActionController that ready to use, read this : https://samsonasik.wordpress.com/2014/11/29/zend-framework-2-using-abstractconsolecontroller-and-consolemodel/
When i do php index.php i get the following error:
Fatal error: Class ‘Symfony\Component\Console\Application’ not found
Help? 😦
Symfony? I’m not sure, but my post is about ZF2 :), you probably have autoload problem
I have the same problem. I`m trying to do cron job. I`m using ZF2 and doctrine.
setup cron ( google for that),point execute php to route of the console controller you created like:
note: check your php bin path for your env php executable file.
Hello Sam
Using Laminas MVC, why I get Application layout response in console when I run “php index.php”? I did not modify anything.
Thank you!
If you are using Laminas MVC, you may need to use laminas-mvc-console https://docs.laminas.dev/laminas-mvc-console/ (deprecated)
Or better, use laminas-cli component instead https://docs.laminas.dev/laminas-cli/