windwalker/console
Windwalker 控制器包
Requires
- php: >=7.1.3
- windwalker/io: ~3.0
- windwalker/structure: ~3.0
Requires (Dev)
- windwalker/test: ~3.0
- 3.x-dev
- dev-master / 3.x-dev
- 3.5.25-beta2
- 3.5.23
- 3.5.22
- 3.5.21
- 3.5.20
- 3.5.19
- 3.5.18
- 3.5.17
- 3.5.16
- 3.5.15
- 3.5.14
- 3.5.13
- 3.5.12
- 3.5.11
- 3.5.10
- 3.5.9
- 3.5.8
- 3.5.7
- 3.5.6
- 3.5.5
- 3.5.4
- 3.5.3
- 3.5.2
- 3.5.1
- 3.5
- 3.4.9
- 3.4.8
- 3.4.7
- 3.4.6
- 3.4.5
- 3.4.4
- 3.4.3
- 3.4.2
- 3.4.1
- 3.4
- 3.3.2
- 3.3.1
- 3.3
- 3.2.8
- 3.2.7
- 3.2.6
- 3.2.5
- 3.2.4
- 3.2.3
- 3.2.2
- 3.2.1
- 3.2
- 3.1.6
- 3.1.5
- 3.1.4
- 3.1.3
- 3.1.2
- 3.1.1
- 3.1
- 3.0.1
- 3.0
- 3.0-beta2
- 3.0-beta
- 2.1.9
- 2.1.8
- 2.1.7
- 2.1.6
- 2.1.5
- 2.1.4
- 2.1.2
- 2.1.1
- 2.1
- 2.0.9
- 2.0.8
- 2.0.7
- 2.0.6
- 2.0.5
- 2.0.4
- 2.0.3
- 2.0.2
- 2.0.1
- 2.0.0
- 2.0.0-beta2
- 2.0.0-beta1
- 2.0.0-alpha
- dev-test
This package is auto-updated.
Last update: 2024-09-18 10:54:06 UTC
README
Windwalker Console 包为您的 CLI 应用程序提供了一个优雅且嵌套的命令结构。
通过 Composer 安装
将以下内容添加到您的 composer.json
文件中的 require 块中。
{ "require": { "windwalker/console": "~3.0" } }
嵌套命令结构
Console Application (RootCommand)
|
----------------------
| |
CommandA CommandB
| |
------------ ------------
| | | |
CommandC CommandD CommandE CommandF
如果我们输入
$ php cli/console.php commandA commandC foo bar -a -bc -d=e --flower=sakura
那么我们将直接跳转到 CommandC
类,接下来的 foo bar
将作为参数。
class CommandC extend AbstractCommand { public function execute() { $arg1 = $this->getArgument(0); // foo $arg2 = $this->getArgument(0); // bar $opt = $this->io->get('d') // e $opt = $this->io->get('flower') // sakura } }
初始化 Console
Console 是主要应用程序,帮助我们创建命令行程序。
cli/console.php
文件中的示例 console 应用程序骨架
<?php // Load the Composer autoloader include __DIR__ . '/../vendor/autoload.php'; use Windwalker\Console\Console; $console = new Console; $console->execute();
execute()
将找到与 CLI 输入参数匹配的命令。如果没有注册任何命令,console 将执行 Default Command
。
默认根命令
RootCommand
是一个继承自基本 Command
的命令对象。它提供了一些有用的辅助函数,我们可以通过输入来列出所有命令
$ php cli/app.php
默认输出为
Windwalker Console - version: 1.0 ------------------------------------------------------------ [console.php Help] The default application command Usage: console.php <command> [option] Options: -h | --help Display this help message. -q | --quiet Do not output any message. -v | --verbose Increase the verbosity of messages. --ansi Set 'off' to suppress ANSI colors on unsupported terminals. Welcome to Windwalker Console.
为 RootCommand 设置处理器
我们可以向每个命令添加闭包,该命令将首先执行此函数。在 $console
上使用 setHandler()
,Console 将自动将代码传递给 RootCommand
<?php // cli/console.php // ... $console->setHandler( function($command) { $command->out('This is default command.'); return 0; // Return exit code. } ); $console->execute();
此代码将执行相同的操作
<?php // cli/console.php // ... $console->getRootCommand() ->setHandler( function($command) { $command->out('This is default command.'); return 0; // Return exit code. } ); $console->execute();
重新输入 $ php cli/console.php
并输出
This is default command.
如果我们想再次获取帮助,只需输入
$ cli/console.php help # OR $ cli/console.php --help
注意:命令只返回介于 0 和 255 之间的整数,
0
表示成功,而其他则表示失败或其他状态。Unix/Linux 的退出代码含义请参阅:退出代码含义
向 Console 添加帮助信息
Console 包含一些帮助信息,如:name
、version
、description
、usage
和 help
。
如果我们将这些信息添加到 Console
// cli/console.php // ... $console = new \Windwalker\Console\Console; $console->setName('Example Console') ->setVersion('1.2.3') ->setUsage('console.php <commands> <arguments> [-h|--help] [-q|--quiet]') ->setDescription('Hello World') ->setHelp( <<<HELP Hello, this is an example console, if you want to do something, see above: $ foo bar -h => foo bar --help --------- $ foo bar yoo -q => foo bar yoo --quiet HELP ); // ...
帮助信息将显示
向 Console 添加一级命令
现在,我们只使用默认的根命令。除了 HelpCommand
之外,没有其他一级命令可供调用。
我们可以通过以下代码添加新命令
<?php // cli/console.php $console->register('foo') ->setDescription('This is first level foo command.') ->setUsage('foo command [--option]') ->setHelp('foo help') ->setHandler( function($command) { $command->out('This is Foo Command executing code.'); } );
然后我们输入
$ cli/console.php foo
我们将得到
This is Foo Command executing code.
如果我们输入 help
$ cli/console.php -h
foo 命令的描述将自动添加到默认命令参数列表中。
声明命令类
我们可以创建自己的命令对象,而不是在运行时设置。
这是一个 FooCommand 声明示例
<?php // src/Myapp/Command/FooCommand.php namespace Myapp\Command; use Windwalker\Console\Command\Command; class FooCommand extends Command { protected $name = 'foo'; protected $usage = 'foo command [--option]'; protected $help = 'foo help'; protected $description = 'This is first level foo command.'; public function initialise() { // We can also set help message in initialise method $this->setDescription('This is first level foo command.') ->setUsage('foo command [--option]') ->setHelp('foo help'); } public function doExecute() { $this->out('This is Foo Command executing.'); } }
然后我们将其注册到 Console 中
<?php // cli/console.php $console->addCommand(new FooCommand);
获取参数和选项
我们可以使用此代码来获取参数和选项,并在 FooCommand
中设置它们。
// src/Myapp/Command/FooCommand.php public function initialise() { // Define options first that we can set option aliases. $this->addOption(array('y', 'yell')) // First element `y` will be option name, others will be alias ->alias('Y') // Add a new alias ->defaultValue(0) ->description('Yell will make output upper case.'); // Global options will pass to every child. $this->addGlobalOption('s') ->defaultValue(0) ->description('Yell will make output upper case.'); } public function doExecute() { $name = #this->getArgument(0); if (!$name) { $this->io->in('Please enter a name: '); } $reply = 'Hello ' . $name; if ($this->getOption('y')) { $reply = strtoupper($reply); } if ($this->getOption('q')) { $reply = strtolower($reply); } $this->out($reply); }
如果我们输入
$ php cli/console.php foo Asika --yell
# OR
$ php cli/console.php foo Asika -y
getOption()
方法将自动检测选项别名,然后我们可以获取
HELLO: ASIKA
注意:我们必须先使用
addOption()
来定义选项,然后才能通过$this->getOption('x')
获取我们想要的输入选项。如果我们不这样做,我们必须使用$this->io->get('x')
来获取选项值,但这种方式不支持选项别名。
添加二级命令以及更多...
现在,FooCommand 是我们命令树中的一级命令,如果我们想在 FooCommand 下添加几个命令,我们可以使用 addCommand()
方法。现在我们向 FooCommand 添加两个 bar
和 yoo
命令。
在运行时添加命令。
我们可以使用 addCommand()
将命令添加为其他命令的子命令。
如果一个命令有一个或多个子命令,参数表示调用与该参数名称相同的子命令。
如果没有子命令,Command对象将运行已设置的处理器闭包,如果没有设置处理器,则运行doExecute()
。然后可以通过$this->getArgument({offset})
获取剩余的参数。
<?php // src/Myapp/Command/FooCommand.php use Windwalker\Console\Option\Option; //... public function initialise() { $this->addCommand('bar') ->description('Bar description.'); $this->addCommand('yoo') ->description('Yoo description.') ->addOption(new Option(array('y', 'yell'), 0)) ->addGlobalOption(new Option('s', 0, 'desc')); }
通过类添加命令
首先声明BarCommand
和YooCommand
类。
<?php // src/Myapp/Command/Foo/BarCommand.php namespace Myapp\Command\Foo; use Windwalker\Console\Command\Command; class BarCommand extends Command { protected $name = 'bar'; protected $usage = 'bar command [--option]'; protected $help = 'bar help'; protected $description = 'This is second level bar command.'; public function initialise() { $this->addOption(new Option(array('y', 'yell'), 0)) ->addGlobalOption(new Option('s', 0, 'desc')); } public function doExecute() { $this->out('This is Bar Command executing.'); $arg1 = $this->getArgument(0); if ($arg1) { $this->out('Argument1: ' . $arg1); } } }
然后注册它们到FooCommand
<?php // src/Myapp/Command/FooCommand.php use Myapp\Command\Foo\BarCommand; use Myapp\Command\Foo\YooCommand; //... public function initialise() { $this->addCommand(new BarCommand) ->addCommand(new YooCommand); }
好的,让我们开始输入
$ cli/console.php foo bar
我们得到
This is Bar Command executing code.
然后输入
$ cli/console.php foo bar sakura
获取
This is Bar Command executing code.
Argument1: sakura
通过路径获取子命令
$command = $console->getCommand('foo/bar'); // BarCommand // OR $command = $command->getChild('foo/bar/baz');
提示器
提示器是一组对话框工具,帮助我们向用户提问。
$prompter = new \Windwalker\Console\Prompter\TextPrompter; $name = $prompter->ask('Tell me your name:', 'default');
或者在构造函数中设置问题。
$prompter = new TextPrompter('Tell me your name: ', $this->io); // If argument not exists, auto ask user. $name = $this->getArgument(0, $prompter);
验证输入值
$prompter = new \Windwalker\Console\Prompter\ValidatePrompter; $prompter->setAttempt(3); $prompter->ask('Please enter username: ');
如果我们没有输入任何内容,ValidatePrompter将尝试问我们三次(我们通过setAttempt()
设置这个数字)。
Please enter username:
Not a valid value.
Please enter username:
Not a valid value.
Please enter username:
Not a valid value.
我们可以设置闭包来验证我们的规则
$prompter->setAttempt(3) ->setNoValidMessage('No valid number.') ->setHandler( function($value) { return $value == 9; } ); $prompter->ask('Please enter right number: ');
结果
Please enter right number: 1
No valid number.
Please enter right number: 2
No valid number.
Please enter right number: 3
No valid number.
如果验证失败,我们可以选择关闭我们的进程
// ... $prompter->failToClose(true, 'Number validate fail and close'); $prompter->ask('Please enter right number: ');
结果
Please enter right number:
No valid number.
Please enter right number:
No valid number.
Please enter right number:
No valid number.
Number validate fail and close
选择列表
$options = array( 's' => 'sakura', 'r' => 'Rose', 'o' => 'Olive' ); $prompter = new \Windwalker\Console\Prompter\SelectPrompter('Which do you want: ', $options); $result = $prompter->ask(); $command->out('You choose: ' . $result);
输出
[s] - sakura
[r] - Rose
[o] - Olive
Which do you want: r
You choose: r
布尔提示器
BooleanPrompter将输入字符串转换为布尔类型,(y, yes, 1) 将是 true
,(n, no, 0, null) 将是 false
。
$prompter = new \Windwalker\Console\Prompter\BooleanPrompter; $result = $prompter->ask('Do you wan to do this [Y/n]: '); var_dump($result);
结果
Do you wan to do this [Y/n]: y
bool(true)
可用的提示器
- TextPrompter
- SelectPrompter
- CallbackPrompter
- ValidatePrompter
- NotNullPrompter
- PasswordPrompter
可用的提示器
HelpCommand
HelpCommand
将自动为我们生成帮助列表。
当我们使用addCommand()
、addOption()
并设置一些描述或其他信息到这些对象中时,它们将保存所有信息。然后当我们输入$ cli/console.php help somethine
或$ cli/console.php somethine --help
,HelpCommand将返回帮助信息给我们。
每个命令都有这些信息,您可以使用setter和getter来访问它们
Name
(命令名称。RootCommand的名称是文件名。)Description
(命令描述,将在帮助输出中的标题后显示。)Usage
(将在当前命令的帮助输出中显示。)Help
(将在帮助输出底部显示,作为当前命令的指南)
控制台信息
Name
(应用程序名称,将在帮助输出中作为标题显示。)Description
(RootCommand描述。)Usage
(RootCommand使用方法。)Help
(RootCommand帮助信息。)
使用自定义描述符
如果您想覆盖应用程序的Descriptor
,可以这样做
<?php use Myapp\Command\Descriptor\XmlDescriptorHelper; use Myapp\Command\Descriptor\XmlCommandDescriptor; use Myapp\Command\Descriptor\XmlOptionDescriptor; // ... $descriptor = new new XmlDescriptorHelper( new XmlCommandDescriptor, new XmlOptionDescriptor ); $console->getRootCommand() ->getChild('help') ->setDescriptor($descriptor); // ...
在不使用控制台的情况下使用命令
我们可以使用Command
而不使用控制台,请参阅Command README。
致谢
Windwalker Console整合了许多来自其他CLI包的想法。以下是Windwalker获得灵感的项目简短列表。