Welcome to Abdul Malik Ikhsan's Blog

Zend Framework 2 : Step by Step Create Console Application

Posted in Tutorial PHP, Zend Framework 2 by samsonasik on September 5, 2012

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

30 Responses

Subscribe to comments with RSS.

    • seyferx said, on May 13, 2014 at 1:35 pm

      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.

  1. Victor De Oliveira said, on January 14, 2013 at 3:14 am

    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

  2. Christoph said, on May 28, 2013 at 4:36 pm

    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?

    • samsonasik said, on May 29, 2013 at 1:09 am

      look at the module.config.php , route should be under console key.

  3. LCervantes said, on July 12, 2013 at 8:55 pm

    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.

  4. ALTAMASH said, on July 27, 2013 at 11:56 am

    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.

    • samsonasik said, on July 28, 2013 at 1:00 am

      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 .

      • ALTAMASH said, on July 29, 2013 at 9:57 am

        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.

      • samsonasik said, on July 29, 2013 at 3:16 pm

        please follow the latest docs : http:/zf2.readthedocs.org

  5. regeint said, on October 21, 2013 at 12:20 pm

    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.

  6. Dennis said, on October 25, 2013 at 4:08 pm

    Pretty simple and just working. Great!

  7. Pieter Massoels (@PMassoels) said, on November 9, 2013 at 11:40 pm

    Thank you. This post helped me alot

  8. Pankaj said, on September 4, 2014 at 2:13 pm

    Please suggest me how can I create ACL in zend 2

  9. Abid Ali said, on November 7, 2014 at 6:05 pm

    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.

    • samsonasik said, on November 7, 2014 at 7:53 pm

      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.

  10. WitteStier said, on December 12, 2014 at 10:54 pm

    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?

  11. Eustáquio Mazinni said, on July 9, 2015 at 12:15 am

    When i do php index.php i get the following error:
    Fatal error: Class ‘Symfony\Component\Console\Application’ not found

    Help? 😦

    • samsonasik said, on July 9, 2015 at 2:26 am

      Symfony? I’m not sure, but my post is about ZF2 :), you probably have autoload problem

      • marcin said, on August 24, 2015 at 8:17 pm

        I have the same problem. I`m trying to do cron job. I`m using ZF2 and doctrine.

      • samsonasik said, on August 25, 2015 at 2:42 am

        setup cron ( google for that),point execute php to route of the console controller you created like:

        /usr/local/php5/bin/php /path/to/your/zf2_app/public/index.php your_zf2_route
        

        note: check your php bin path for your env php executable file.

  12. juliangorge said, on October 26, 2022 at 3:09 pm

    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!


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: