命令行应用Command Line Applications

CLI应用即是运行在命令行窗体上的应用。 主要用来实现后台任务, 命令行工具等。

CLI applications are executed from the command line. They are useful to create cron jobs, scripts, command utilities and more.

结构Structure

最小结构的CLI程序如下:

A minimal structure of a CLI application will look like this:

  • app/config/config.php
  • app/tasks/MainTask.php
  • app/cli.php <– main bootstrap file

创建引导Creating a Bootstrap

普通的MVC程序中,启动文件用来启动整个应用。和web应用不同, 此处应用中我们使用cli.php来作为启动文件。

As in regular MVC applications, a bootstrap file is used to bootstrap the application. Instead of the index.php bootstrapper in web applications, we use a cli.php file for bootstrapping the application.

下面是一个简单的启动文件示例:

Below is a sample bootstrap that is being used for this example.

  1. <?php
  2. use Phalcon\DI\FactoryDefault\CLI as CliDI,
  3. Phalcon\CLI\Console as ConsoleApp;
  4. define('VERSION', '1.0.0');
  5. //Using the CLI factory default services container
  6. $di = new CliDI();
  7. // Define path to application directory
  8. defined('APPLICATION_PATH')
  9. || define('APPLICATION_PATH', realpath(dirname(__FILE__)));
  10. /**
  11. * Register the autoloader and tell it to register the tasks directory
  12. */
  13. $loader = new \Phalcon\Loader();
  14. $loader->registerDirs(
  15. array(
  16. APPLICATION_PATH . '/tasks'
  17. )
  18. );
  19. $loader->register();
  20. // Load the configuration file (if any)
  21. if(is_readable(APPLICATION_PATH . '/config/config.php')) {
  22. $config = include APPLICATION_PATH . '/config/config.php';
  23. $di->set('config', $config);
  24. }
  25. //Create a console application
  26. $console = new ConsoleApp();
  27. $console->setDI($di);
  28. /**
  29. * Process the console arguments
  30. */
  31. $arguments = array();
  32. foreach($argv as $k => $arg) {
  33. if($k == 1) {
  34. $arguments['task'] = $arg;
  35. } elseif($k == 2) {
  36. $arguments['action'] = $arg;
  37. } elseif($k >= 3) {
  38. $arguments['params'][] = $arg;
  39. }
  40. }
  41. // define global constants for the current task and action
  42. define('CURRENT_TASK', (isset($argv[1]) ? $argv[1] : null));
  43. define('CURRENT_ACTION', (isset($argv[2]) ? $argv[2] : null));
  44. try {
  45. // handle incoming arguments
  46. $console->handle($arguments);
  47. }
  48. catch (\Phalcon\Exception $e) {
  49. echo $e->getMessage();
  50. exit(255);
  51. }

上面的代码可以使用如下方式执行:

This piece of code can be run using:

  1. $ php app/cli.php
  2. This is the default task and the default action

任务Tasks

这里的任务同于web应用中的控制器。 任一 CLI 应用程序都至少包含一个mainTask 及一个 mainAction, 每个任务至少有一个mainAction, 这样在使用者未明确的 指定action时 此mainAction就会执行。

Tasks work similar to controllers. Any CLI application needs at least a mainTask and a mainAction and every task needs to have a mainAction which will run if no action is given explicitly.

下面即是一个mainTask的例子( app/tasks/MainTask.php ):

Below is an example of the app/tasks/MainTask.php file

  1. <?php
  2. class MainTask extends \Phalcon\CLI\Task
  3. {
  4. public function mainAction() {
  5. echo "\nThis is the default task and the default action \n";
  6. }
  7. }

处理动作参数Processing action parameters

CLI应用中, 开发者也可以在action中处理传递过来的参数, 下面的例子中已经对传递过来的参数进行了处理。

It’s possible to pass parameters to actions, the code for this is already present in the sample bootstrap.

如果你使用下面的参数和动作运行应用程序:

If you run the the application with the following parameters and action:

  1. <?php
  2. class MainTask extends \Phalcon\CLI\Task
  3. {
  4. public function mainAction() {
  5. echo "\nThis is the default task and the default action \n";
  6. }
  7. /**
  8. * @param array $params
  9. */
  10. public function testAction(array $params) {
  11. echo sprintf('hello %s', $params[0]) . PHP_EOL;
  12. echo sprintf('best regards, %s', $params[1]) . PHP_EOL;
  13. }
  14. }
  1. $ php app/cli.php main test world universe
  2. hello world
  3. best regards, universe

链中运行任务Running tasks in a chain

CLI应用中可以在一个action中执行另一action. 要实现这个需要在 DI 中设置console.

It’s also possible to run tasks in a chain if it’s required. To accomplish this you must add the console itself to the DI:

  1. <?php
  2. $di->setShared('console', $console);
  3. try {
  4. // handle incoming arguments
  5. $console->handle($arguments);
  6. }

然后开发者即可在一个action中使用用其它的action了. 下面即是例子:

Then you can use the console inside of any task. Below is an example of a modified MainTask.php:

  1. <?php
  2. class MainTask extends \Phalcon\CLI\Task
  3. {
  4. public function mainAction() {
  5. echo "\nThis is the default task and the default action \n";
  6. $this->console->handle(array(
  7. 'task' => 'main',
  8. 'action' => 'test'
  9. ));
  10. }
  11. public function testAction() {
  12. echo '\nI will get printed too!\n';
  13. }
  14. }

当然, 通过扩展 \Phalcon\CLI\Task 来实现如上操作会是一个更好主意。

However, it’s a better idea to extend \Phalcon\CLI\Task and implement this kind of logic there.