自定义 CLI 命令

使用 CLI 命令和使用路由等其他模块一样的轻松愉快,也有一些不同的地方,这就是 CLI 命令的由来。CLI 命令是不需要为其定义路由的简单类,可以让开发人员更简单的创建一些工具。例如,数据库迁移、数据库填充、检查计划任务(cronjob)状态,甚至为公司做一个自定义代码生成器。

运行命令

命令是在项目根目录中通过命令行来执行的。在 /app/system 同级目录中,提供了一个自定义脚本 spark 用于运行任何 CLI 命令:

> php spark

在不指定命令名称的情况下调用命令,会显示帮助页面并展示出所有可用的命令。你应该将命令名称作为运行该命令的第一个参数传递:

> php spark migrate

一些命令需要使用到更多的参数,你需要直接写在后面并以空格分隔开:

> php spark db:seed DevUserSeeder

对于 CodeIgniter 提供的命令,如果不提供必需的参数,则将提示你输入正确运行所需的参数:

> php spark migrate:version
> Version?

使用帮助命令

你可以使用 help 命令来获得 CLI 帮助:

> php spark help db:seed

创建新的命令

你可以非常容易的创建新的命令,并在开发中使用。每个类都必须独立成一个文件,且必须继承自 CodeIgniter\CLI\BaseCommand,同时需要实现 run() 方法。

为了在 CLI 命令中列出你的命令并添加相应帮助功能,需要使用到以下属性:

  • ($group): 一个字符串,用于描述列出命令时命令所属的组。例如(数据库)
  • ($name): 表示命令名称的字符串。例如(migrate:create)
  • ($description): 描述命令的字符串。例如(创建一个新的迁移文件)
  • ($usage): 描述命令用法的字符串。例如(migrate:create [migration_name] [选项])
  • ($arguments): 描述每个命令参数的字符串数组。例如(’migration_name’ => ‘迁移文件名’)
  • ($options): 描述每个命令选项的字符串数组。例如(’-n’ => ‘设置迁移命名空间’)

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

文件位置

命令必须放在名为 Commands 的目录中。但是,该目录可以位于 自动加载器 可以找到的任何位置。该目录可以在 /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 = '显示基本应用信息';

    public function run(array $params)
    {

    }
}

如果运行 list 命令,你将在其自己的 demo 组下看到新命令。如果你仔细观察,就会很容易的发现它们是如何工作的。$group 属性说明他所在的组,及存在的所有命令,并会指出他在哪个列表之下。

$name 属性是命令用来被调用的名字,仅有的要求是不能包含空格,并且所有字符必须是命令行有效字符。按照惯例命令行都是小写,通过使用命名空间的冒号,可以规避掉重名的风险。

最后一个属性 $description 是在 list 命令中显示的一条描述信息,用来描述命令的用途。

run()

run() 方法在命令运行时会被调用,$params 数组是紧跟在命令名之后的 CLI 参数列表,例如下面的 CLI 内容:

> php spark foo bar baz

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

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

This can also be accessed through the CLI library, but this already has your command removed from the string. These parameters can be used to customize how your scripts behave.

在我们的 demo 命令中,run 方法类似如下写法:

public function run(array $params)
{
    CLI::write('PHP Version: '. CLI::color(phpversion(), 'yellow'));
    CLI::write('CI Version: '. CLI::color(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'));
}

BaseCommand

所有命令必须继承自 BaseCommand 类,它拥有一些很有用的方法,在创建自己的命令时应熟悉这些方法。在 $this->logger 上也有一个 Logger

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

此方法使你可以在当前命令执行期间运行其他命令:

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

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

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

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

getPad($array, $pad)
参数:
  • $array (array) – $key => $value 数组
  • $pad (integer) – 填充空格数

一个为 $key => $value 数组输出计算填充的方法。填充可用于在 CLI 中输出格式化的表格:

$pad = $this->getPad($this->options, 6);
foreach ($this->options as $option => $description)
{
        CLI::write($tab . CLI::color(str_pad($option, $pad), 'green') . $description, 'yellow');
}

// 输出应该会像这样
-n                  设置迁移命名空间
-r                  覆盖文件