参数,变得简单
有一天,我决定一劳永逸地打败这个怪物。我伪造了一个秘密武器——一个作为存储的函数、一个解析器和一个参数查询函数。
// You can initialize it with a multiline string:
arg("
-a --alpha bool Some explanation about this option
-b --beta bool Beta has some notes too
-n --number int Some number you need for the script
- --douglas int There is no short form of this
-o --others str A string of other things
");
// ... and now you have your arguments nicely wrapped up:
print arg("alpha"); // returns the value of -a or --alpha
print arg("a"); // same thing
print arg(); // returns the whole parsed array
print arg(1); // returns the first unnamed argument
print arg(2); // returns the second unnamed argument
print arg("douglas",42); // value of "douglas", or a reasonable default
说明
-
您需要做的就是将参数列表写成多行字符串。四列,看起来很有帮助,但arg() 会解析您的行并自动找出参数。
-
用两个或多个空格分隔列 - 就像你做的那样。
-
解析后,每个项目将由一个字段数组表示,分别命名为 char、word、type 和 help。如果参数没有短 (char) 或长 (word) 版本,只需使用破折号。显然,两者都不是。
-
类型就是它们看起来的样子:bool 表示参数后面没有值;如果缺少则为假,如果存在则为真。 int 和 str 类型意味着必须有一个值,并且 int 确保它是一个整数。不支持可选参数。值可以用空格或等号分隔(即“-a=4”或“-a 4”)
-
在第一次调用之后,您将所有参数整齐地组织在一个结构中(转储它,您会看到),您可以按名称或编号查询它们的值。
-
函数 arg() 具有第二个默认参数,因此您永远不必担心缺少值。
arg() 函数本身
function arg($x="",$default=null) {
static $arginfo = [];
/* helper */ $contains = function($h,$n) {return (false!==strpos($h,$n));};
/* helper */ $valuesOf = function($s) {return explode(",",$s);};
// called with a multiline string --> parse arguments
if($contains($x,"\n")) {
// parse multiline text input
$args = $GLOBALS["argv"] ?: [];
$rows = preg_split('/\s*\n\s*/',trim($x));
$data = $valuesOf("char,word,type,help");
foreach($rows as $row) {
list($char,$word,$type,$help) = preg_split('/\s\s+/',$row);
$char = trim($char,"-");
$word = trim($word,"-");
$key = $word ?: $char ?: ""; if($key==="") continue;
$arginfo[$key] = compact($data);
$arginfo[$key]["value"] = null;
}
$nr = 0;
while($args) {
$x = array_shift($args); if($x[0]<>"-") {$arginfo[$nr++]["value"]=$x;continue;}
$x = ltrim($x,"-");
$v = null; if($contains($x,"=")) list($x,$v) = explode("=",$x,2);
$k = "";foreach($arginfo as $k=>$arg) if(($arg["char"]==$x)||($arg["word"]==$x)) break;
$t = $arginfo[$k]["type"];
switch($t) {
case "bool" : $v = true; break;
case "str" : if(is_null($v)) $v = array_shift($args); break;
case "int" : if(is_null($v)) $v = array_shift($args); $v = intval($v); break;
}
$arginfo[$k]["value"] = $v;
}
return $arginfo;
}
// called with a question --> read argument value
if($x==="") return $arginfo;
if(isset($arginfo[$x]["value"])) return $arginfo[$x]["value"];
return $default;
}
我希望这可以帮助很多迷失的灵魂,就像我一样。愿这个小函数阐明不必编写帮助和解析器并使它们保持同步的美丽......此外,一旦解析,这种方法非常快,因为它缓存了变量,所以你可以调用它尽可能多随心所欲。它就像一个超全球。
也可以通过我的GitHub Gist 获得。