CLI stands for Command Line Interface. CLI applications are executed from the command line or a shell prompt. One of the benefits of CLI applications is that they do not have a view layer (only potentially echoing output on screen) and can be run more than one at a time. Some common usages are cron job tasks, manipulation scripts, import data scripts, command utilities and more.
You can create a CLI application in Phalcon, using the Phalcon\Cli\Console class. This class extends from the main abstract application class, and uses a directory in which the Task scripts are located. Task scripts are classes that extend Phalcon\Cli\Task and contain the code that we need executed.
The directory structure of a CLI application can look like this:
In the above example, the cli.php is the entry point of our application, while the src/tasks directory contains all the task classes that handle each command.
NOTE: Each task file and class must be suffixed with Task. The default task (if no parameters have been passed) is MainTask and the default method to be executed inside a task is main
As seen above, the entry point of our CLI application is the cli.php. In that script, we need to bootstrap our application with relevant services, directives etc. This is similar to the all familiar index.php that we use for MVC applications.
First we need to create all the necessary services for our CLI application. We are going to create a loader to autoload our tasks, the CLI application, a dispatcher and a CLI Console application. These are the minimum amount of services that we need to instantiate to create a CLI application.
Create the Phalcon autoloader and register the namespace to point to the src/ directory.
NOTE: If you decided to use the Composer autoloader in your composer.json, you do not need to register the loader in this application
We need a Dependency Injection container. You can use the Phalcon\Di\FactoryDefault\Cli container, which already has services registered for you. Alternatively, you can always use the Phalcon\Di and register the services you need, one after another.
CLI applications need a specific dispatcher. Phalcon\Cli\Dispatcher offers the same functionality as the main dispatcher for MVC applications, but it is tailored to CLI applications. As expected, we instantiate the dispatcher object, we set our default namespace and then register it in the DI container.
As you can see in the above, we use the $argv to receive what has been passed through the command line, and we split those arguments accordingly to understand what task and action need to be invoked and with what parameters.
So for the following example:
php ./cli.php users recalculate 10
Our application will invoke the UsersTask, call the recalculate action and pass the parameter 10.
In the code above, we use our console object and call handle with the calculated parameters. The CLI application will do the necessary routing and dispatch the task and action requested. If an exception is thrown, it will be caught by the catch statements and errors will be displayed on screen accordingly.
Tasks are the equivalent of controllers in an MVC application. Any CLI application needs at least one task called MainTask and a mainAction. Any task defined needs to have a mainAction which will be called if no action is defined. You are not restricted to the number of actions that each task can contain.
An example of a task class (src/Tasks/MainTask.php) is:
01: This is the default task and the default action
02: Also handle the print action
03: Print action executed also
This technique allows you to run any task and any action from any other task. However, it is not recommended because it could lead to maintenance nightmares. It is better to extend Phalcon\Cli\Task and implement your logic there.
CLI applications can also handle different modules, the same as MVC applications. You can register different modules in your CLI application, to handle different paths of your CLI application. This allows for better organization of your code and grouping of tasks.
You can register a frontend and backend module for your console application as follows: