douglasgreen / opt-parser
PHP 的命令行选项解析器
Requires
- php: >=8.1
- douglasgreen/utility: ^0.5
Requires (Dev)
- douglasgreen/config-setup: dev-main
- phpstan/phpstan: ^1.11
- phpunit/phpunit: ^10.5
- rector/rector: ^1.2
- symplify/easy-coding-standard: ^12.3
README
PHP 的命令行选项解析器
设置
使用 Composer 添加项目。
composer require douglasgreen/utility
关于
OptParser 是 PHP 程序中获取命令行选项的内置 getopt()
的替代品。它比 getopt 更好,因为它
- 支持定义多个选项类型和别名。
- 允许混合位置和命名的选项。
- 允许定义独立的命令,每个命令都有自己的用法。
- 自动打印格式化的程序帮助信息。
- 检查未识别的参数,以防止无效的程序执行。
命令
程序接受一种或多种用法。用法是一系列选项。
选项
选项是以下之一
- 命令,即请求的操作的名称。
- 术语,即位置参数。
- 参数,即以连字符为前缀的名称,有一个必需的参数。
- 标志,即以连字符为前缀的名称,没有参数。
如果有命令,每个用法只能有一个命令,并且它必须排在第一位。如果有多个用法,每个用法都必须有一个命令来区分它。
如果有术语,它们是必需的,并且必须跟在命令后面,如果有命令的话。
参数和标志放在最后。顺序很重要,以避免歧义。
命令和术语是必需的,因为它们是位置的,但参数和标志是可选的,因为它们是命名的。
命名约定
命令、标志和参数的长名称都必须遵循 Unix 命名约定
- 全部小写
- 以字母开头
- 包含字母、数字和连字符,但不包含下划线
- 以字母或数字结尾
这也就是所谓的短横线命名法。一个例子是 file-path
。
命令匹配
每个用法由其命令区分。每个命令都是不同的,因此在运行时只能有一个用法可能匹配。
参数别名
每个参数可以有一个或多个别名。如果别名短(只有一个字符),则使用单个连字符调用,如 -h
。如果别名长(超过一个字符),则使用两个连字符调用,如 --help
。
短别名可以是小写或大写。
每个别名只能定义一次。
参数名称
每个参数至少必须有一个长别名。该参数指定的第一个长别名用作参数名称。您必须使用其名称检索参数。
命令、参数和标志可以有别名。但术语没有标记,因此它只有一个名称,没有别名。
参数类型
大多数允许的参数类型列表来自 PHP 验证过滤器 的列表。添加了一些自定义类型。允许的类型包括
BOOL
- 有效的布尔值(对于 "1"、"true"、"on" 和 "yes" 为 true)DATE
- 有效的日期值DATETIME
- 有效的日期和时间值DIR
- 可读的目录路径DOMAIN
- 有效的域名长度和价值EMAIL
- 有效的电子邮件地址FIXED
- 有效的定点数FLOAT
- 有效的浮点数,允许逗号和科学记数法INFILE
- 可读的文件路径INTERVAL
- 有效的日期间隔字符串描述INT
- 有效的整数,允许八进制和十六进制表示法IP_ADDR
- 有效的IP地址MAC_ADDR
- 有效的MAC地址OUTFILE
- 可写父目录的文件路径,可能存在或不存在STRING
- 任何字符串TIME
- 有效的时值URL
- 有效的URLUUID
- 有效的通用唯一ID,可能包含或不含连字符
这些作为OptParser::addParam()
和OptParser::addTerm()
的第二个参数指定,因为参数和术语接受参数,因此有类型。这些类型会在程序帮助信息中打印,并在处理参数时自动应用,如果验证失败,则程序将报错并终止。
参数过滤器
您也可以将自定义过滤器回调作为OptParser::addParam()
和OptParser::addTerm()
的最后一个参数定义。过滤器可以进行自定义验证。如果验证成功,您可以返回原始值或其过滤版本。如果验证失败,则抛出一个带有描述性错误消息的BadArgumentException
,程序将报错并终止。
格式化
标志不能组合,例如-a -b -c
不能写成-abc
。这是为了防止错误地输入一个连字符,如输入为-pass而不是--pass,导致错误地得到选项-a -p和-s。
每个标志或参数与其参数之间必须有一个空格或等号分隔。
参数列表可以用--
结尾,之后可以跟非选项。程序会忽略非选项,但会返回它们与匹配的使用方法。您可以使用OptResult::getNonoptions()
检索它们。
获取结果
结果由OptParser::parse()
作为OptResult
对象返回,我将其称为$input
,因为它代表用户输入。
您可以使用$input->get($name)
检索用户匹配的参数,其中name是选项名称。您也可以使用属性方式检索参数,即使用$input-$name
。属性名称中的驼峰式命名映射到选项名称中的连字符命名。例如,$input->filePath
会映射到file-path
选项名称。
程序接口
使用OptParser
- 使用程序名称和描述创建一个
OptParser
实例。当显示程序帮助时使用。 - 使用对
$optParser
的链式调用,对addCommand()
、addTerm()
、addParam()
和addFlag()
进行操作,以定义这些类型的选项。 - 通过调用
$optParser->addUsage()
将选项组合在一起,添加特定的选项名称组合。如果有唯一的用法,可以调用更简单的$optParser->addUsageAll()
来一次性添加所有选项。 - 使用
$input = $optParser->parse();
解析参数。 - 使用
$command = $input->getCommand();
获取执行的命令,以确定如何解释输出。 - 使用
$input->get($name)
或更简洁的$input-$name
获取当前命令的每个选项名称。
示例用法
文件中有示例用法。您也可以用-h
运行程序,查看示例帮助输出。
示例帮助
示例帮助输出如下所示
User Manager
A program to manage user accounts
Usage:
sample-usage --help
sample-usage add username:STRING email:STRING --password=STRING --role=STRING
sample-usage delete username:STRING
sample-usage list --output=OUTFILE --verbose
Commands:
add | a Add a new user
delete | d Delete an existing user
list | l List all users
Terms:
username: STRING Username of the user
email: STRING Email of the user
Parameters:
--password | -p = STRING Password for the user
--role | -r = STRING Role of the user
--output | -o = OUTFILE Output file for the list command
Flags:
--help | -h Display program help
--verbose | -v Enable verbose output
--quiet | -q Suppress output
这显示了
- 程序名称
- 程序描述
- 用法列表,包括始终可用的
--help
。每个用法按顺序呈现:命令、术语、参数和标志。 - 术语类型用冒号标记,参数类型用等号标记,可用于传递参数。类型名称全部大写。
- 每个部分都显示其别名,以管道符号交替排列,首先是主名称,然后是描述。
常见问题解答
为什么使用OptParser而不是getopt()?
OptParser支持位置参数,进行错误检查,并打印格式良好的帮助信息。getopt()
不执行这些操作。
我应该使用什么选项类型?
命令只是为了区分用法。如果您有两个或三个不同类型的参数,您不会混淆,则可以将其作为术语。但通常,您应该给出类似参数的选项名称,它们接受一个参数,以及不需要参数的标志。命名选项更难混淆。
addUsage()和addUsageAll()之间的区别是什么?
OptParser::addUsageAll()
适用于只有一个用例的简单情况。调用此函数可添加所有术语、参数和标志,而无需重复它们的名称。OptParser::addUsage()
适用于具有多个命令的情况。调用此函数可按名称添加每个命令及其相关的术语、参数和标志。