命令行应用(Command Line Applications)

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

结构(Structure)

最小结构的 CLI 程序如下:

  • app/config/config.php
  • app/tasks/MainTask.php
  • app/cli.php <– 主要启动文件

创建引导(Creating a Bootstrap)

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

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

  1. <?php
  2.  
  3. // 使用CLI工厂类作为默认的服务容器
  4. $di = new Phalcon\Di\FactoryDefault\Cli();
  5.  
  6. // 定义应用目录路径
  7. defined('APPLICATION_PATH') || define('APPLICATION_PATH', realpath(dirname(__FILE__)));
  8.  
  9. /**
  10. * 注册类自动加载器
  11. */
  12. $loader = new \Phalcon\Loader();
  13. $loader->registerDirs(
  14. array(
  15. APPLICATION_PATH . '/tasks'
  16. )
  17. );
  18. $loader->register();
  19.  
  20. // 加载配置文件(如果存在)
  21. if (is_readable(APPLICATION_PATH . '/config/config.php')) {
  22. $config = Phalcon\Config\Adapter\Php(APPLICATION_PATH . '/config/config.php', TRUE);
  23. $di->set('config', $config);
  24. }
  25.  
  26. // 创建console应用
  27. $console = new Phalcon\Cli\Console();
  28. $console->setDI($di);
  29.  
  30. try {
  31. $console->handle();
  32. } catch (\Phalcon\Exception $e) {
  33. echo $e->getMessage();
  34. exit(255);
  35. }

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

  1. $ php app/cli.php --task=main --action=main --params=1 --params=2
  2.  
  3. 这样程序就会执行任务main以及动作main,并传递参数 `array(1, 2)`

通过 argv 解析应用参数:

  1. <?php
  2.  
  3. use Phalcon\Di\FactoryDefault\Cli as CliDI,
  4. Phalcon\Cli\Console as ConsoleApp;
  5.  
  6. define('VERSION', '1.0.0');
  7.  
  8. // 使用CLI工厂类作为默认的服务容器
  9. $di = new CliDI();
  10.  
  11. // 定义应用目录路径
  12. defined('APPLICATION_PATH')
  13. || define('APPLICATION_PATH', realpath(dirname(__FILE__)));
  14.  
  15. /**
  16. * 注册类自动加载器
  17. */
  18. $loader = new \Phalcon\Loader();
  19. $loader->registerDirs(
  20. array(
  21. APPLICATION_PATH . '/tasks'
  22. )
  23. );
  24. $loader->register();
  25.  
  26. // 加载配置文件(如果存在)
  27. if (is_readable(APPLICATION_PATH . '/config/config.php')) {
  28. $config = include APPLICATION_PATH . '/config/config.php';
  29. $di->set('config', $config);
  30. }
  31.  
  32. // 创建console应用
  33. $console = new ConsoleApp();
  34. $console->setDI($di);
  35.  
  36. /**
  37. * 处理console应用参数
  38. */
  39. $arguments = array();
  40. foreach ($argv as $k => $arg) {
  41. if ($k == 1) {
  42. $arguments['task'] = $arg;
  43. } elseif ($k == 2) {
  44. $arguments['action'] = $arg;
  45. } elseif ($k >= 3) {
  46. $arguments['params'][] = $arg;
  47. }
  48. }
  49.  
  50. // 定义全局的参数, 设定当前任务及动作
  51. define('CURRENT_TASK', (isset($argv[1]) ? $argv[1] : null));
  52. define('CURRENT_ACTION', (isset($argv[2]) ? $argv[2] : null));
  53.  
  54. try {
  55. // 处理参数
  56. $console->handle($arguments);
  57. } catch (\Phalcon\Exception $e) {
  58. echo $e->getMessage();
  59. exit(255);
  60. }

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

  1. $ php app/cli.php
  2.  
  3. 这样程序会直接执行默认的任务及默认动作.

从命令行参数列表中获取选项

  1. <?php
  2.  
  3. $shortopts = "";
  4. $shortopts .= "n:"; // -n="Phalcon"
  5. $shortopts .= "d::"; // -d
  6. $shortopts .= "D"; // -D
  7.  
  8. $options = getopt(
  9. $shortopts,
  10. array(
  11. 'namespace:', // 必选项 --namespace=Phalcon
  12. 'task::', // 可选项 --task=main
  13. 'dev::', // 可选项 --dev=true
  14. 'debug' // 无值 --debug
  15. )
  16. );
  17.  
  18. $opts = getopt(NULL, array('namespace:', 'dev::','action::'));
  19.  
  20. // 创建console应用
  21. $console = new \Phalcon\Cli\Console();
  22. $console->setDI($di);
  23.  
  24. // 处理console应用参数
  25. $arguments = array(
  26. 'namespace' => \Phalcon\Arr::get($opts, 'namespace'),
  27. 'task' => \Phalcon\Arr::get($opts, 'task'),
  28. 'action' => \Phalcon\Arr::get($opts, 'action')
  29. );
  30.  
  31. try {
  32. $console->handle($arguments);
  33. } catch (\Phalcon\Exception $e) {
  34. echo $e->getMessage();
  35. }

使用命令行选项类(Cli Options)

  1. <?php
  2.  
  3. $opts = new \Phalcon\Cli\Options('Phalcon Task CLI');
  4. $opts->add([
  5. 'type' => \Phalcon\Cli\Options::TYPE_STRING,
  6. 'name' => 'namespace',
  7. 'shortName' => 'n',
  8. 'required' => true,
  9. 'defaultValue' => 'Phalcon'
  10. ]);
  11. $opts->add([
  12. 'type' => \Phalcon\Cli\Options::TYPE_STRING,
  13. 'name' => 'task',
  14. 'shortName' => 't',
  15. 'required' => true,
  16. 'defaultValue' => 'main'
  17. ]);
  18. $opts->add([
  19. 'type' => \Phalcon\Cli\Options::TYPE_STRING,
  20. 'name' => 'action',
  21. 'shortName' => 'a',
  22. 'required' => true,
  23. 'defaultValue' => 'main'
  24. ]);
  25. $vals = $opts->parse();
  26. if (!$vals) {
  27. return;
  28. }
  29.  
  30. // 创建console应用
  31. $console = new \Phalcon\Cli\Console();
  32.  
  33. // 处理console应用参数
  34. $arguments = array(
  35. 'namespace' => \Phalcon\Arr::get($vals, 'namespace'),
  36. 'task' => \Phalcon\Arr::get($vals, 'task'),
  37. 'action' => \Phalcon\Arr::get($vals, 'action')
  38. );
  39.  
  40. try {
  41. $console->handle($arguments);
  42. } catch (\Phalcon\Exception $e) {
  43. echo $e->getMessage();
  44. }

任务(Tasks)

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

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

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

处理动作参数(Processing action parameters)

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

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

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

我们可以使用下面的命令行及参数执行程序:

  1. $ php app/cli.php main test world universe
  2.  
  3. hello world
  4. best regards, universe

链中运行任务(Running tasks in a chain)

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

  1. <?php
  2.  
  3. $di->setShared('console', $console);
  4.  
  5. try {
  6. // Handle incoming arguments
  7. $console->handle($arguments);
  8. } catch (\Phalcon\Exception $e) {
  9. echo $e->getMessage();
  10. exit(255);
  11. }

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

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

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

运行 MVC 应用(Running MVC Application)

使用MVC架构来开发的程序,在命令行下运行命令如下:

  1. $ php app/index.php --url="/auth/login"

原文: http://www.myleftstudio.com/reference/cli.html