fostam / getopts
灵活的PHP命令行参数解析器,具有自动帮助信息生成和验证支持
Requires
- php: >=5.6
Requires (Dev)
- phpunit/phpunit: ^5.5|^6.5
README
灵活的PHP命令行参数解析器,具有自动帮助信息生成和验证支持。
特性
- 灵活直观的配置
- 支持长/短选项、选项参数、默认值、可增加/可取消选项等。
- 非选项参数处理
- 自动错误处理和帮助文本生成
- 选项/参数验证
安装
安装GetOpts最简单的方式是通过使用 composer
$> composer require fostam/getopts
使用方法
<?php include "vendor/autoload.php"; $getopts = new Fostam\GetOpts\Handler(); $getopts->addOption('verboseLevel') ->short('v') ->long('verbose') ->description('increase verbosity') ->incrementable(); $getopts->addArgument('outputFile') ->name('output-file') ->required(); $getopts->parse(); // show parsed options and arguments for demonstration purposes var_dump($getopts->get());
根据给定的选项和参数,输出可能如下($>
是命令行提示符)。
选项和参数值
$> php test.php -vvv hello
array(2) {
["verboseLevel"]=>
int(3)
["outputFile"]=>
string(5) "hello"
}
帮助文本
$> php test.php -h
Usage: test.php [-v] OUTPUT-FILE
-v increase verbosity
缺少参数
$> php test.php
test.php: missing arguments
Usage: test.php [-v] OUTPUT-FILE
Try 'test.php --help' for more information
选项配置
要向GetOpts处理器添加新选项,请调用 addOption()
方法。它接受该选项的内部名称作为参数。此内部名称随后用于在解析结果中引用选项值,且必须在整个选项和参数名称中唯一。
$option = $handler->addOption('inputFile');
addOption()
返回一个可以进一步通过调用方法进行配置的新 Option
对象。每个配置方法再次返回选项对象本身,以便可以进行链式调用。
如果调用不匹配的选项配置或未满足命名约束,则抛出 OptionConfigException
异常。
短名称
$option->short('f');
这设置了该选项的短名称。短名称仅允许单个字母数字字符。在本例中,标志 -f
会匹配此选项。
注意,不同的短选项可以单独传递,也可以合并,例如 -a -b -c
或 -abc
,或者任何组合。
长名称
$option->long('filename');
选项的长名称可以由一个或多个字母数字字符组成,包括 _
和 -
。在本例中,传递 --filename
会匹配该选项。
对于每个选项,必须配置长名称、短名称或两者。
描述
对于自动帮助文本生成,可以提供可选描述。
$option->description('input file with data to be processed');
将为该选项生成此帮助文本
-f, --filename=INPUT-FILE input file with data to be processed
选项参数
$option->short('f')->argument('input-file');
指定此选项需要额外的参数,例如 -f myfile.txt
。
传递给 argument()
的名称用于自动 用法 字符串/帮助文本生成。它使用其大写版本。
如果缺少参数,则解析会失败。
如果选项具有长名称,则可以带有或没有 =
传递参数,即可以是 --file file1.txt
或 --file=file1.txt
。
多次出现
需要参数的选项可以配置为多次出现。在这种情况下,即使只出现一次,该选项也始终返回一个 array
作为值。
$option->short('f')->argument('input-file')->multiple();
传递 -f file1.txt -f file2.txt
的调用会产生此结果数组
array(2) { [0]=> string(9) "file1.txt" [1]=> string(9) "file2.txt" }
可增加
如果选项的值应在每次提供时递增,则可以将其设置为可增加。
$handler->addOption('verboseLevel')->short('v')->incrementable();
-v -v -v
或 -vvv
因此会对 verboseLevel
选项的结果为 3
。
可以通过传递整数给 incrementable()
来更改默认增加值 1
。
$handler->addOption('verboseLevel')->short('v')->incrementable(5);
可递增的选项不能有选项参数(即incrementable()
和argument()
/multiple()
是互斥的)。
必需
$option->required();
这将使选项成为必填项。如果未提供,解析将失败。
默认值
默认情况下,未提供的选项在结果数组中将变为null
。可以通过配置可选默认值来改变这种行为
$handler->addOption('inputFile')->short('f')->defaultValue('file1.txt'); $handler->addOption('maxValue')->short('m')->defaultValue(5);
可否决
标记选项(即不带参数且不是可递增的选项)在具有长名称时可以被设置为可否决。要否决选项,长名称前缀为no
。
$option->long('test')->negatable();
对于--test
,结果值将像往常一样为true
,但对于--notest
,结果值将为false
。这在与true
的默认值结合时特别有用。
验证
可以为选项指定一个可选的验证函数
$option->validator(function($value) { if ($value < 0 || $value > 50) { return false; } return true; });
validator()
接受任何callable
作为选项,例如函数、闭包、类/对象方法等。可调用函数接收选项值作为参数,并根据验证结果返回true
或false
。
如果任何选项验证器返回false
,则选项解析失败。
参数配置
参数配置与选项配置类似。要添加参数,调用处理器的addArgument()
方法,返回一个Argument
对象
$option = $handler->addArgument('outputFile');
与Option
一样,Argument
配置方法是可链的。参数的名称必须在所有选项和参数名称中是唯一的
如果调用不匹配的参数配置或未满足命名约束,将抛出ArgumentConfigException
异常。
名称
$arg->name('output-file');
此名称用于创建自动的Usage字符串。如果未提供,则使用默认的"ARGUMENT"
。如果您依赖自动的Usage字符串生成,则应始终配置name
,以便创建的文本对用户友好。
多次出现
可以配置参数多次传递。为了避免模糊配置,只能配置最后传递的参数。
$arg->name('output-file')->multiple();
在此结果数组中,此参数将始终返回一个array
。
默认值
省略的必需参数在结果对象中将始终为null
。当配置默认值时,将返回此值。
$arg->name('output-file')->defaultValue('file.txt');
必需
$arg->name('output-file')->required();
这将使参数成为必需。为了避免歧义,必需参数不能位于非必需参数之前。
验证
参数验证与选项验证的方式相同
$arg->validator(function($value) { if ($value < 0 || $value > 50) { return false; } return true; });
给定的callable
将参数值作为输入传递,并必须返回true
或false
。
解析结果
通用获取器
$result = $handler->get();
或
$verbosity = $handler->get('verbosity');
使用通用的get()
方法,可以检索任何结果 - 选项或参数。如果没有传递参数,将返回包含选项和参数结果的关联数组。当传递名称时,返回相应的选项或参数值。如果该名称未配置,则抛出LogicException
。
有关结果值的详细信息,请参阅选项和参数。
选项
$optionArray = $handler->getOptions();
每个已配置的选项都将以结果数组中的键的形式出现,无论是否提供。每个选项的值取决于配置
- 如果没有提供,则值是
null
,或者已配置的默认值 - 不需要参数的选项是
boolean
,即当提供时它们将是true
- 可否决的选项在它们的否定形式中提供时将被设置为
false
- 可递增的选项以
integer
返回 - 选项参数始终以
string
返回
参数
$argumentArray = $handler->getArguments();
已配置的每个参数都将作为结果数组中的键存在,无论是否给出。如果未给出,则每个参数的值为null
,或者配置的可选默认值。否则,值是一个字符串
。
脚本名称
脚本名称是已执行的PHP脚本的名称
$> php myscript.php -v file.txt
$scriptName = $handler->getScriptName(); // would return "myscript.php"
解析错误
如果输入参数解析失败,例如,由于未满足要求约束或参数验证器返回了false
,则立即停止参数处理,并执行以下步骤
- 将错误信息打印到STDERR
- 创建并打印到STDERR的用法字符串
- 如果未关闭帮助文本生成,则将帮助文本选项的提示打印到STDERR
- 使用
exit(2)
停止脚本执行,导致命令返回码为2
- 因此,在调用
$handler->parse()
之后的代码都不会执行
如果需要,可以关闭自动错误处理。有关详细信息,请参阅高级功能。
帮助文本
当给出默认帮助选项(短-h
或长--help
)时,立即停止参数处理,并执行以下步骤
- 创建并打印到STDOUT的用法字符串
- 创建并打印到STDOUT的帮助文本
- 使用
exit(0)
停止脚本执行,导致命令返回码为0
- 因此,在调用
$handler->parse()
之后的代码都不会执行
可以自定义或完全停用短和长帮助选项名称。有关详细信息,请参阅高级功能。
高级功能
输入参数
默认情况下,输入参数来自$_SERVER['argv']
。如果您不希望这样 - 例如,因为您正在使用通过其他方式提供脚本参数的框架 - 您可以覆盖默认行为,并将可选的自定义输入参数数组传递给处理器的parse()
方法。
$handler->parse([ 'myscript.php', '-v', '-f', 'file.txt' ]);
该数组必须由字符串组成,其中每个字符串代表脚本的一个参数。参数按照数组的内部顺序获取;数组的键被忽略。
重要:数组的第一个元素必须是执行PHP脚本的脚本名称。这是由$handler->getScriptName()
返回的值。如果您没有或不需要脚本名称,请将空字符串作为第一个元素。
错误处理
如果您不希望自动错误处理接管,例如,因为您想控制脚本何时退出,或您想用不同的语言提供错误消息,您可以禁用默认行为
$handler->disableErrorHandling();
当禁用时,如果发生解析错误,$handler->parse()
方法会抛出以下UsageException
异常之一
UnrecognizedOptionException
:提供了一个未配置的选项MissingOptionsException
:未提供一些必需选项InvalidOptionException
:选项的验证器返回了false
MissingOptionArgumentException
:未提供选项的参数MissingArgumentsException
:未提供一些必需参数TooManyArgumentsException
:传递了比配置更多的参数InvalidArgumentException
:参数的验证器返回了false
异常的消息是使用自动错误处理时打印的错误文本。一些异常有额外的获取数据的方法,可用于创建更详细的自定义错误消息。
您仍然可以获取自动的用法字符串
$handler->getUsageString();
帮助选项
可以设置一个附加的自定义帮助文本,该文本打印在自动帮助文本下方。自定义文本应以换行符(PHP_EOL
)结尾。
$handler->setExtraHelpText($txt);
当配置了很多选项后,用法字符串可能会变得相当长。如果您更希望有一个简短的用法字符串而不包含选项详情,可以启用简洁的用法字符串。此时,选项将以"[选项] ..."
的形式在字符串中表示。
$handler->enableTerseUsage();
通过以下处理器方法,可以更改内置帮助函数的选项
$handler->setHelpOptionLong('help'); $handler->setHelpOptionShort('h');
通过将两个值都设置为空字符串或false
,可以禁用帮助文本功能。在这种情况下,解析错误时的帮助提示也不再显示。
您仍然可以访问生成的帮助文本
$handler->getHelpText();