webfiori / cli
用于简化使用PHP创建基于命令行应用程序的类库。
Requires
- webfiori/file: 1.3.*
README
一个类库,可以帮助使用PHP编写具有最小依赖的基于命令行的应用程序。
内容
支持的PHP版本
功能
- 帮助创建基于命令行的应用程序。
- 支持交互式模式。
- 支持ANSI输出。
- 支持实现自定义输入和输出流。
- 能够为命令编写测试并使用测试自动化工具测试它们。
示例应用程序
示例应用程序可以在以下位置找到: https://github.com/WebFiori/cli/tree/main/example
安装
要安装库,只需将其包含在composer.json
的require
部分: "webfiori\cli":"*"
。
创建和运行命令
创建命令
创建新命令的第一步是创建一个扩展webfiori\cli\CLICommand
类的新的类。该类CLICommand
是一个实用类,它具有可以用来读取输入、发送输出和使用命令行参数的方法。
该类有一个必须实现的方法。该方法的主体中的代码将代表命令的逻辑。
<?php //File 'src/SampleCommand.php' use webfiori\cli\CLICommand; class SampleCommand extends CLICommand { public function __construct(){ parent::__construct('say-hi'); } public function exec(): int { $this->println("Hi People!"); } }
运行命令
webfiori\cli\Runner
类是用于管理执行命令逻辑的类。为了运行命令,必须创建该类的实例并使用它来注册命令并开始运行应用程序。
要注册命令,使用Runner::register()
方法。要启动应用程序,使用Runner::start()
方法。
// File src/main.php require_once '../vendor/autoload.php'; use webfiori\cli\Runner; use SampleCommand; $runner = new Runner(); $runner->register(new SampleCommand()); exit($runner->start());
现在,如果打开终端并执行以下命令
php main.php say-hi
输出将是字符串Hi People!
。
参数
参数是从终端传递到PHP进程值的方式。它们可以用来配置命令的执行。例如,一个命令可能需要某种类型的文件作为输入。
向命令添加参数
参数可以按照以下方式添加到类的构造函数中
<?php //File 'src/SampleCommand.php' use webfiori\cli\CLICommand; use webfiori\cli\Option; class SampleCommand extends CLICommand { public function __construct(){ parent::__construct('say-hi', [ '--person-name' => [ Option::OPTIONAL => true ] ]); } public function exec(): int { $this->println("Hi People!"); } }
参数可以作为关联数组或webfiori\cli\Argument
类型对象的数组提供。在关联数组的情况下,索引是参数的名称,索引的值是子关联数组选项。每个参数都可以有以下选项
optional
:一个布尔值。如果设置为true,则表示该参数是可选的。默认为false。default
:参数的默认值,如果未提供则使用。description
:参数的描述,当执行命令help
时将显示。values
:参数可以具有的值集。如果提供,则只允许列表上的值。
可以使用webfiori\cli\Option
类来访问选项。
访问参数值
通过使用方法 CLICommand::getArgValue(string $argName)
来访问参数的值。如果提供了参数,该方法将返回其值作为 string
。如果没有提供,则返回 null
。
<?php //File 'src/SampleCommand.php' use webfiori\cli\CLICommand; use webfiori\cli\Option; class SampleCommand extends CLICommand { public function __construct(){ parent::__construct('say-hi', [ '--person-name' => [ Option::OPTIONAL => true ] ]); } public function exec(): int { $personName = $this->getArgValue('--person-name'); if ($personName !== null) { $this->println("Hi %s!", $personName); } else { $this->println("Hi People!"); } } }
交互式模式
交互模式是一种可以在同一PHP进程中保持应用程序运行并执行多个命令的方法。要启动应用程序的交互模式,在启动应用程序时添加参数 -i
,如下所示
php main.php -i
这将在终端显示以下输出
>> Running in interactive mode. >> Type command name or 'exit' to close. >>
帮助
命令
库中默认提供的命令之一是 帮助
命令。它可以用来显示所有已注册命令的帮助说明。
注意:为了使用此命令,必须使用方法
Runner::register()
进行注册。
设置帮助说明
帮助说明由创建命令的开发者在实现期间提供。说明可以作为描述设置在扩展了类 webfiori\cli\CLICommand
的类的构造函数中。描述可以针对命令及其参数设置。
<?php //File 'src/SampleCommand.php' use webfiori\cli\CLICommand; use webfiori\cli\Option; class GreetingsCommand extends CLICommand { public function __construct() { parent::__construct('hello', [ '--person-name' => [ Option::DESCRIPTION => 'Name of someone to greet.', Option::OPTIONAL => true ] ], 'A command to show greetings.'); } public function exec(): int { $name = $this->getArgValue('--person-name'); if ($name === null) { $this->println("Hello World!"); } else { $this->println("Hello %s!", $name); } return 0; } }
运行help
命令
帮助命令可以通过两种方式使用,一种是为应用程序显示一般帮助,另一种是为特定命令显示。
通用帮助
要显示应用程序的一般帮助,可以执行以下命令。
//File 'src/main.php' php main.php help
此命令的输出将如下所示
Usage:
command [arg1 arg2="val" arg3...]
Global Arguments:
--ansi:[Optional] Force the use of ANSI output.
Available Commands:
help: Display CLI Help. To display help for specific command, use the argument "--command-name" with this command.
hello: A command to show greetings.
open-file: Reads a text file and display its content.
注意:根据已注册的命令,输出可能不同。
特定命令的帮助
要显示特定命令的帮助说明,可以使用参数 --command-name
包含命令的名称,如下所示
//File 'src/main.php' php main.php help --command-name=hello
此命令的输出将如下所示
hello: A command to show greetings.
Supported Arguments:
--person-name:[Optional] Name of someone to greet.
单元测试命令
库提供了辅助类 webfiori\cli\CommandTestCase
,可以用来为不同命令编写单元测试。开发者只需扩展该类并使用实用方法编写测试。该类基于 PHPUnit。
该类有两个可用于执行测试的方法
CommandTestCase::executeSingleCommand()
:用于一次运行一个命令并返回其输出。CommandTestCase::executeMultiCommand()
:用于注册多个命令,设置默认命令和/或运行已注册的其中一个命令。
第一个方法适用于验证一个特定命令的输出。第二个方法对于模拟具有多个命令的应用程序的执行非常有用。
两种方法都支持模拟参数向量和用户输入。
namespace tests\cli; use webfiori\cli\CommandTestCase; class HelloCommandTest extends CommandTestCase { /** * @test */ public function test00() { //Verify test results $this->assertEquals([ "Hello World!\n" ], $this->executeSingleCommand(new HelloWorldCommand())); $this->assertEquals(0, $this->getExitCode()); } }
测试示例可以在这里找到