bobdenotter/commando

PHP CLI 命令行风格

1.0.1 2023-04-13 18:19 UTC

This package is auto-updated.

Last update: 2024-09-14 14:19:28 UTC


README

注意:这是 https://github.com/nategood/commando 的分支,兼容 PHP 8.1 及更高版本。

优雅的 PHP CLI 库

Commando 是一个 PHP 命令行界面库,它美化和简化了编写用于命令行使用的 PHP 脚本。

为什么?

PHP 的 $argv 魔术变量和全局 $_SERVER['argv'] 让我感到恶心,getopt 并没有好太多,而且大多数其他 PHP CLI 库在许多情况下都过于臃肿。Commando 在没有大量开销的情况下专注于业务,当处理 CLI 输入时,移除了常见的样板代码,同时提供了一个干净且易于阅读的界面。

安装

Commando 需要您运行 PHP 8.1 或更高版本。

Commando 符合 PSR-0 规范,并可以使用 Composer 安装。将 bobdenotter/commando 添加到您的 composer.json

"require": {
    "bobdenotter/commando": "*"
}

如果您是 Composer 新手...

目前通过 Composer 安装是唯一支持的方式。

示例

以下是一个 PHP Commando 脚本的示例,它对 Commando 的功能进行了很好的介绍。假设它在一个名为 hello.php 的文件中。

<?php

require_once 'vendor/autoload.php';

$hello_cmd = new Commando\Command();

// Define first option
$hello_cmd->option()
    ->require()
    ->describedAs('A person\'s name');

// Define a flag "-t" a.k.a. "--title"
$hello_cmd->option('t')
    ->aka('title')
    ->describedAs('When set, use this title to address the person')
    ->must(function($title) {
        $titles = array('Mister', 'Mr', 'Misses', 'Mrs', 'Miss', 'Ms');
        return in_array($title, $titles);
    })
    ->map(function($title) {
        $titles = array('Mister' => 'Mr', 'Misses' => 'Mrs', 'Miss' => 'Ms');
        if (array_key_exists($title, $titles))
            $title = $titles[$title];
        return "$title. ";
    });

// Define a boolean flag "-c" aka "--capitalize"
$hello_cmd->option('c')
    ->aka('capitalize')
    ->aka('cap')
    ->describedAs('Always capitalize the words in a name')
    ->boolean();

// Define an incremental flag "-e" aka "--educate"
$hello_cmd->option('e')
    ->aka('educate')
    ->map(function($value) {
        $postfix = array('', 'Jr', 'esq', 'PhD');
        return $postfix[$value] === '' ? '' : " {$postfix[$value]}";
    })
    ->count(4);

$name = $hello_cmd['capitalize'] ? ucwords($hello_cmd[0]) : $hello_cmd[0];

echo "Hello {$hello_cmd['title']}$name{$hello_cmd['educate']}!", PHP_EOL;

运行它

> php hello.php Nate
Hello, Nate!

> php hello.php --capitalize nate
Hello, Nate!

> php hello.php -c -t Mr 'nate good'
Hello, Mr. Nate Good!

> php hello.php -ceet Mr 'nate good'
Hello, Mr. Nate Good esq!

注意事项

  • Commando 实现 ArrayAccess,因此当您想要检索它的值时,它表现得就像一个数组
  • 对于“匿名”(即非命名标志)参数,我们根据它们的数字索引来访问它们
  • 我们可以通过标志名称或其别名在数组中访问选项值
  • 我们可以在选项定义中直接使用闭包来执行验证和映射操作

内置帮助

Commando 内置了自动 --help 支持。使用此标志调用您的脚本将打印出一个基于您的选项定义和 Commando 设置的漂亮帮助页面。如果您定义了一个别名为 'help' 的选项,它将覆盖此内置支持。

help screenshot

错误消息

默认情况下,Commando 将捕获解析过程中发生的异常。相反,Commando 将打印格式化、用户友好的错误消息到标准错误,并以代码 1 退出。如果您希望 Commando 在这些情况下抛出异常,请调用您的 Command 实例上的 doNotTrapErrors 方法。

error screenshot

命令方法

这些选项在“命令”级别上起作用。

useDefaultHelp (bool help)

Commando 的默认行为是提供 --help 选项,它会输出一个根据您的选项定义生成的有用帮助页面。通过调用 useDefaultHelp(false) 禁用此功能。

setHelp (string help)

用于在帮助页面之前添加的文本。使用此功能描述命令的高级概念以及一些命令的示例用法。

printHelp()

打印命令的默认帮助。如果您希望在没有传递任何参数的情况下输出帮助,则很有用。

beepOnError (bool beep=true)

当发生错误时,打印字符以使终端“哔哔”。

getOptions

返回一个数组,其中包含命令提供的每个选项的 Options

getFlags

返回一个只包含命令提供的标志的选项数组。

getArguments

返回一个只包含命令提供的参数的选项数组。数组的顺序与参数的顺序相同。

getFlagValues

返回命令提供的参数的值所组成的关联数组。例如:array('f' => 'value1')

getArgumentValues

返回命令提供的参数值的数组。例如:array('value1', 'value2')

命令选项定义方法

这些选项在"选项"级别上工作,即使它们被链接到一个Command实例

option (mixed $name = null)

别名: o

定义一个新的选项。当name被设置时,该选项将是一个命名的"标志"选项。可以是短形式选项(例如,选项-f的缩写为f)或长形式(例如,选项--foo的长写形式为foo)。当没有定义name时,该选项是一个匿名参数,并且在未来通过其位置引用。

flag (string $name)

option相同,但是只能用于定义"标志"类型的选项(即必须在命令行上使用-标志指定的选项)。

argument ()

option相同,但是只能用于定义"参数"类型的选项(即那些在命令行上不使用-标志指定的选项)。

alias (string $alias)

别名: aaka

为命名的选项添加别名。此方法可以多次调用以添加多个别名。

description (string $description)

别名: ddescribedescribedAs

描述此选项的文本。此文本将用于构建"帮助"页面,因此它面向最终用户。

require (bool $require)

别名: rrequired

要求指定此标志。

needs (string|array $options)

别名:无

要求设置其他$options,以便使用此选项。

must (Closure $rule)

别名: N/A

定义一个规则来验证输入。接受一个接受字符串$value并返回一个布尔值,表示$value是否有效的函数。

map (Closure $map)

别名: castcastTo

对此选项的值执行映射操作。接受一个接受字符串$value并返回混合值的函数(你可以映射到任何你想要的)。

reduce (Closure $reducer [, mixed $seed])

别名: listeachevery

在命令中的每个选项实例上执行累积/还原函数。接受一个累积函数,并返回混合值(你可以返回任何值)。如果你还提供了选项的映射,映射将在传递给累积函数之前对每个值执行。如果提供了$seed值,则将使用此值作为默认值。

签名: function(mixed $accumulated, mixed $value) : mixed

  • $accumulated: null|Option::default|mixed (函数返回的最后一个值,选项默认值或null。)
  • $value: mixed (选项后面的值。如果提供了映射,则是映射函数返回的值。)
  • return: mixed (你想要的任何东西。最后一个返回值成为解析后的选项的值。)

referToAs (string $name)

别名: titlereferredToAs

添加一个名称,通过该名称可以引用参数选项。使帮助文档对匿名的"参数"选项更清晰。

boolean ()

别名: N/A

指定标志是一个布尔类型标志。

increment (int $max)

别名: icountrepeatsrepeatable

指定标志为计数类型标志。每次在命令中使用标志时,标志的值都会递增,直到达到$max的值。可以将设置为incrementboolean类型的选项组合在一起。

默认值(混合$defaultValue

别名:defaultsTo

如果未指定值,则默认为$defaultValue

boolean()类型标志的情况下,当标志存在时,此选项的值为$defaultValue的否定。也就是说,如果您有一个默认值为true的标志-b,当-b作为命令行标志存在时,该选项的值将是false

文件()

别名:expectsFile

为此选项指定的值必须是有效的文件路径。当使用相对路径时,它们将被转换为完全限定的文件路径,并且也支持globbing。请参阅file.php示例。

boolean ()

别名: N/A

指定标志是一个布尔类型标志。

默认值(混合$defaultValue

别名:defaultsTo

如果未指定值,则默认为$defaultValue

boolean()类型标志的情况下,当标志存在时,此选项的值为$defaultValue的否定。也就是说,如果您有一个默认值为true的标志-b,当-b作为命令行标志存在时,该选项的值将是false

文件()

别名:expectsFile

为此选项指定的值必须是有效的文件路径。当使用相对路径时,它们将被转换为完全限定的文件路径,并且也支持globbing。请参阅file.php示例。

贡献

Commando强烈鼓励提交拉取请求。当提交拉取请求时,请

  • 所有拉取请求都应针对dev分支(不是master
  • 确保您的代码遵循在PSR-1PSR-2中概述的编码标准
  • 确保您为您的更改添加适当的测试覆盖率
  • 通过phpunit ./tests在测试目录中运行所有单元测试
  • 在适当的地方添加注释,并添加描述性的拉取请求信息

灵感

在MIT许可下发布。

变更日志

1.0.0

  • PR #1 PHP 8.1兼容修复。

v0.4.0

  • 停止支持5.4和5.5,提高次要版本号
  • PR #93 特性:添加reducer选项
  • PR #95 修复:在Windows OS上删除tput调用
  • PR #101 修复:如果该选项实际上未被使用,则仅评估选项的'needs'约束
  • PR #76 修复:使用匿名参数时,修复非空getArgumentValues数组

v0.3.0

  • 删除PHP 5.3支持

v0.2.9

  • PR #63 特性:增量标志
  • PR #60 次要:getDescription方法

v0.2.8

  • 修复了#34的bug

v0.2.7

  • getOptions添加(附带一些更好的文档)

v0.2.6

  • 添加了对“needs”的支持,以定义选项之间的依赖关系(感谢@enygma) PR #31
  • 修复了长参数名称的问题 问题 #30

v0.2.5

  • 修复了布尔选项的默认值,自动将布尔选项的默认值设置为false(不太可能,但可能是一个破坏性更改) PR #19

v0.2.4

  • 添加了为选项定义默认值的能力

v0.2.3

  • 改进了帮助格式 PR #12

v0.2.2

  • 修复了打印重复帮助的bug PR #10

v0.2.1

  • 添加了要求选项为有效文件路径或glob的支持
  • 返回一个完全限定的文件路径名(例如,转换相对路径)
  • 在glob模式的情况下返回一个文件路径数组
  • 请参考examples目录中的file.php示例

v0.2.0

这次更新的主要目标是更好地区分标志选项和参数选项。在Commando中,标志是我们定义的选项,当在命令行中指定时需要指定名称。参数是不以这种方式命名的选项。在下面的示例中,'-f' 和 '--long' 被描述为Commando术语中的“标志”类型选项,分别具有 'value1' 和 'value2' 的值,而 value3、value4 和 value5 被描述为“参数”类型选项。

php command.php -f value1 --long value2 value3 value4 value5
  • 添加了Command::getArguments()以返回一个“参数”类型的 Option 数组(请参阅argumentsVsFlags.php示例)
  • 添加了Command::getFlags()以返回一个“标志”类型的 Option 数组(请参阅argumentsVsFlags.php示例)
  • 添加了Command::getArgumentValues()以返回“参数”的所有值数组
  • 添加了Command::getFlagValues()以返回“标志”的所有值数组
  • Command现在实现了Iterator接口,并将遍历所有选项,从参数开始,然后按字母顺序继续到标志
  • 现在可以使用Command::flag($name)、Command::argument(),以及Command::option($name)来定义选项
  • 添加了为参数添加“标题”的功能,以便通过标题引用参数,使帮助文档更加清晰(运行help.php示例)
  • 清理了生成的帮助文档
  • 修复了显示错误时出现额外彩色红色线条的问题

v0.1.4

  • 修复了多词选项值的问题

v0.1.3

  • 在Terminal中添加了蜂鸣声支持
  • 添加了Commando::beepOnError()

v0.1.2

  • 更新了Terminal,以正确使用tput