创建 Spark 命令

虽然通过 CLI 使用控制器(就像使用其他任何路由一样)很方便,但你可能会遇到需要一些不同功能的情况。这时 Spark 命令就派上用场了。它们是简单的类,不需要定义路由,非常适合构建开发者可用的工具,让工作更轻松,无论是处理迁移或数据库填充、检查 cronjob 状态,还是为你公司构建自定义代码生成器。

创建新命令

你可以非常轻松地创建新命令用于自己的开发。每个类必须位于自己的文件中,并且必须继承 CodeIgniter\CLI\BaseCommand,并实现 run() 方法。

应使用以下属性,以便在 CLI 命令列表中显示你的命令并为其添加帮助功能:

  • $group:一个字符串,用于描述命令在列出时所属的组。例如:Database

  • $name:一个字符串,用于描述命令的名称。例如:make:controller

  • $description:一个字符串,用于描述命令。例如:Generates a new controller file.

  • $usage:一个字符串,用于描述命令的用法。例如:make:controller <name> [options]

  • $arguments:一个字符串数组,用于描述每个命令参数。例如:'name' => 'The controller class name.'

  • $options:一个字符串数组,用于描述每个命令选项。例如:'--force' => 'Force overwrite existing file.'

帮助描述将根据上述参数自动生成。

文件位置

命令必须存储在名为 Commands 的目录中。但是,该目录必须位于 PSR-4 命名空间中,以便 自动加载器 能够找到它。这可以是 app/Commands,或者你为所有项目开发保存命令的目录,例如 Acme/Commands

备注

执行命令时,完整的 CodeIgniter CLI 环境已经加载,因此可以获取环境信息、路径信息,并使用创建控制器时会用到的任何工具。

示例命令

让我们通过一个示例命令来逐步了解,该命令的唯一功能是报告应用程序本身的基本信息,仅用于演示目的。首先在 app/Commands/AppInfo.php 创建一个新文件。它应包含以下代码:

<?php

namespace App\Commands;

use CodeIgniter\CLI\BaseCommand;
use CodeIgniter\CLI\CLI;

class AppInfo extends BaseCommand
{
    protected $group       = 'Demo';
    protected $name        = 'app:info';
    protected $description = 'Displays basic application information.';

    public function run(array $params)
    {
        // ...
    }
}

如果运行 list 命令,你将看到新命令列在它自己的 Demo 组下。仔细观察,你应该很容易理解它是如何工作的。$group 属性只是告诉它如何将此命令与所有其他存在的命令组织在一起,告诉它在哪个标题下列出。

$name 属性是此命令的调用名称。唯一的要求是它不能包含空格,且所有字符在命令行本身上必须是有效的。不过按照惯例,命令是小写的,通过在命令名称本身使用冒号来进行进一步的命令分组。这有助于避免多个命令出现命名冲突。

最后一个属性 $description 是一个短字符串,在 list 命令中显示,应描述命令的功能。

run()

run() 方法是执行命令时调用的方法。$params 数组是你可用的命令名称之后的任何 CLI 参数列表。如果 CLI 字符串是:

php spark foo bar baz

那么 foo 是命令名称,$params 数组将是:

<?php

$params = ['bar', 'baz'];

这也可以通过 CLI 库访问,但它已经从字符串中移除了你的命令。这些参数可用于自定义脚本的行为方式。

我们的演示命令的 run() 方法可能类似于:

<?php

namespace App\Commands;

use CodeIgniter\CLI\BaseCommand;
use CodeIgniter\CLI\CLI;

class AppInfo extends BaseCommand
{
    // ...

    public function run(array $params)
    {
        CLI::write('PHP Version: ' . CLI::color(PHP_VERSION, 'yellow'));
        CLI::write('CI Version: ' . CLI::color(\CodeIgniter\CodeIgniter::CI_VERSION, 'yellow'));
        CLI::write('APPPATH: ' . CLI::color(APPPATH, 'yellow'));
        CLI::write('SYSTEMPATH: ' . CLI::color(SYSTEMPATH, 'yellow'));
        CLI::write('ROOTPATH: ' . CLI::color(ROOTPATH, 'yellow'));
        CLI::write('Included files: ' . CLI::color(count(get_included_files()), 'yellow'));
    }
}

有关详细信息,请参阅 CLI 库 页面。

命令终止

默认情况下,命令以成功代码 0 退出。如果在执行命令时遇到错误,可以在 run() 方法中使用 return 语言结构并附带退出代码来终止命令。

例如,return EXIT_ERROR;

如果命令(例如通过 crontab 运行)在系统级别进行调试,这种方法会很有帮助。

你可以使用在 app/Config/Constants.php 文件中定义的 EXIT_* 退出代码常量。

BaseCommand

所有命令必须继承的 BaseCommand 类有几个在创建自己命令时应熟悉的有用工具方法。它还在 $this->logger 处提供了一个 Logger

class CodeIgniter\CLI\BaseCommand
call(string $command[, array $params = []])
参数:
  • $command (string) -- 要调用的另一个命令的名称。

  • $params (array) -- 提供给该命令的额外 CLI 参数。

此方法允许你在当前命令执行期间运行其他命令:

<?php

$this->call('command_one');
$this->call('command_two', $params);
showError(Throwable $e)
参数:
  • $e (Throwable) -- 用于错误报告的异常。

一种便捷方法,用于在 CLI 中保持一致且清晰的错误输出:

<?php

try {
    // ...
} catch (\Exception $e) {
    $this->showError($e);
}
showHelp()

一种显示命令帮助的方法:(用法、参数、描述、选项)

setPad(string $item, int $max, int $extra = 2, int $indent = 0) string
参数:
  • $item (string) -- 字符串项。

  • $max (integer) -- 最大尺寸。

  • $extra (integer) -- 在末尾添加的额外空格数。

  • $indent (integer) -- 缩进空格数。

填充字符串,使所有标题长度相同,以便整齐地对齐描述:

use CodeIgniter\CLI\CLI;

$length = max(array_map('strlen', array_keys($this->options)));

foreach ($this->options as $option => $description) {
    CLI::write(CLI::color($this->setPad($option, $length, 2, 2), 'green') . $description);
}
/*
 * Output will be:
 *  -n     Set migration namespace
 *  -g     Set database group
 *  --all  Set for all namespaces, will ignore (-n) option
 */
getPad($array, $pad)

自 4.0.5 版本弃用: 改用 CodeIgniter\CLI\BaseCommand::setPad()

参数:
  • $array (array) -- $key => $value 数组。

  • $pad (integer) -- 填充空格数。

一种计算 $key => $value 数组输出填充的方法。填充可用于在 CLI 中输出格式良好的表格。