monolyth / cliff
Monolyth 无框架的命令行界面
Requires
- php: >=8.1
- monomelodies/reflex: ^0.3.0
- ulrichsg/getopt-php: ^4.0
Requires (Dev)
- phpunit/phpunit: ^9.5
README
Monolyth 无框架的命令行界面
安装
使用 Composer
composer required monolyth/cliff
用法
cliff
是 Monolyth 的命令行工具。它允许您从 CLI 创建和运行命令,支持参数。
vendor/bin/cliff namespace/of/command [arguments]
cliff
会将给定的命令进行标准化,将命名空间转换为大写,并用反向斜杠替换正斜杠。因此,命令 my/command
将解析为类名为 My\Command
,Composer 的自动加载器必须能够加载此类。
如果命令的类名本身是 Command
,cliff
将自动添加它。因此,如果没有找到类 My\Command
,它将尝试查找 My\Command\Command
,然后才会放弃。
为了方便起见,所有 cliff
命令类 必须 继承 Monolyth\Cliff\Command
(见下文)。
编写命令
编写一个扩展 Monolyth\Cliff\Command
的类。最好也将类本身命名为 Command
,这样您在 CLI 上可以省略它,但这不是必需的
<?php namespace My\Module; use Monolyth\Cliff; class Command extends Cliff\Command { }
每当调用一个 cliff
命令时,它的魔法方法 __invoke
会被调用。传递给调用的任何 参数 将按顺序原样传递。所以,如果您的命令期望 path
和 filename
作为参数,您的定义将如下所示
<?php //... public function __invoke(string $path, string $filename) { // ...do your thang... }
如果命令被调用时缺少任何必需的参数,cliff
将自动显示一个有用的错误消息(见下文)。
如果命令类没有扩展
Monolyth\Cliff\Command
,一切都将按正常进行 - 但显然您将无法使用 Cliff 的参数解析、帮助功能(见下文)等。Cliff 将显示一个警告;如果您不使用 Cliff,那么您就不应该使用 Cliff ;)
选项
“选项”是前面带有 -
或 --
的调用组件。在类 Unix 系统中,单破折号表示“后面跟单个字母,可选一个值”,而双破折号表示“后面跟多个字母,一个等号和一个更复杂的值”。cliff
遵循这个传统。
所有选项都设置为命令的属性。选项被“标准化”,即选项 my-user-name
最终将变为 $this->myUserName
。
实现者应定义所有选项为公共属性。任何非公共属性都不是选项,例如依赖注入。
定义简写选项
任何选项的默认值也是定义一个简写版本,其第一个字母小写,例如选项 --password
也可以作为 -p
使用。对于具有许多参数的复杂命令,这可能会导致冲突。cliff
将首先使用重复参数的大写版本。如果这也已被占用,它将忽略重复的简写选项。
例如,如果您的命令类指定了 file
、format
和 foo
属性,则只有 -f
用于 ---file
和 -F
用于 format
可用作简写。
您可以使用属性显式指定您想要的简写版本
<?php //... #[\Monolyth\Cliff\Alias("o")] public $foo;
请注意,除非选项定义为仅简写(即具有单个字母名称的属性),否则只有长选项变体被设置为属性。换句话说,只有类上定义的属性被使用。
长选项名称
使用 $snakeCased
选项属性时,CLI 中使用短横线分隔的选项(例如 --snake-cased
)会进行转换,反之亦然。看在上帝的分上,不要在公共属性的第一个字符使用大写字母;一方面,这看起来很难看;更重要的是,Cliff 不会对此进行考虑,所以 $Foo
将变成 ---foo
,这没有任何意义(并且很可能导致错误)。
选项类型
选项有三种变体:必需的、可选的和空的(空选项默认为可选)。在您的命令类中定义这些很简单
<?php class Command extends \Monolyth\Cliff\Command { public string $requiredOption; // No default value, so this is required public string $optionalOption = 'foo'; // The default value means this is optional public bool $emptyOption = false; // Boolean options are per defintion empty }
注意,标记选项为“必需的”仅仅意味着在使用选项时必须传递一个值;选项本身永远不能是“必需的”。如果您总是需要在运行命令时传递值,请使用 __invoke
方法的 参数。
换句话说,可选选项可以具有值或布尔值。
如果一个可选参数的默认值为空字符串,它将被设置为 NULL
,这样各种 PHP 合并操作符就能按预期工作。因此,没有默认值的可选字符串选项必须是可以为空的(?string
)。
选项属性只允许 string
、bool
和 array
类型。这是 CLI 接口的特点。
否定空选项
如果设置了空选项,默认的布尔值将被 否定。所以如果默认值是 true
,设置该选项会使它变为 false
,反之亦然。通常,默认值为 false
会更有意义,但这可能有助于您的代码逻辑变得独特。
数组选项
如果选项被指定为数组(字符串数组),它将自动允许传递多个值,例如。
$ vendor/bin/cliff my/command --test=foo --test=bar
与字符串选项一样,空字符串将被强制转换为 null
。
手动传递选项
有时您可能需要从另一个脚本中运行命令,例如在使用 Monolyth\Croney
调度器时。要覆盖传递给命令的选项,请将包含所需命令的数组传递给构造函数
<?php $command = new Foo\Command(['--bar', 'baz']); $command->execute();
这与使用 vendor/bin/cliff foo --bar baz
来调用相同。
链式命令
可以使用您选择的操作系统的标准功能进行命令链或输出重定向。例如,在类 Unix 系统上,这可以通过管道(|
)和尖括号(<
)操作符来完成。在 Cliff 0.7 之前,使用了一个更复杂的机制,但为什么要重新发明轮子呢,对吧?
可以使用 PHP 的标准 STDIN
流来 读取 输入。要将某些内容输出给其他脚本或命令作为输入,只需简单地 echo
它。
此 readme 的先前版本有如下示例:一个生成用户列表的命令,另一个仅按女性用户过滤的命令。现在可以通过类似以下方式实现
vendor/bin/cliff users | vendor/bin/cliff females > females.csv
文档、帮助和错误报告
通过反射,利用了类的 doccomments、__invoke
方法和选项属性。
使用类的 doccomment 来描述一般用法。这与使用 -h[elp]
选项调用常见的 Unix 命令类似。
使用 __invoke
方法的 doccomment 来描述命令期望的参数。当任何必需的参数缺失时,将显示此消息。
使用任何选项属性的 doccomment,当它作为值传递给 -h
或 --help
选项时,将显示详细的帮助。此选项在 Command
基类中定义。您可以在自己的命令中覆盖它,但它在基构造函数中处理(您可能不想覆盖它...)。
如果 __invoke
方法抛出任何未捕获的异常,将显示其消息,并返回非零退出状态。请注意,退出状态 1 保留用于当缺失必需参数时。
预加载文件
类似于vendor/autoload.php
,你的命令可能需要一些引导,例如如果你正在使用一个框架。你可以使用Monolyth\Cliff\Preload("filename")
属性来自动化这个过程(而不是使用略显丑陋的require_once
调用)。这个属性应该放置在类上。
多个Preload
属性按照顺序包含。注意,所有路径都应该相对于getcwd()
。如果你更喜欢使用require_once
,请随意。:-)