PHP的getopt()不允许将参数及其可选值与空格分开,需要用' ='分隔。或不分开:
# test.php uses getopt('a::')
> php test.php -a 3 // incorrect
> php test.php -a=3 // correct
> php test.php -a3 // correct
但另一方面,你可以使用空格来分隔参数及其所需的值(一个指定为getopt(' a:'))。为了使用空格的一致性和直观性,我想在getopt()处理之前纠正命令行 - 我有一个正则表达式替换了#ab; -abc bc'与' -abc = bc'。
但事实证明修改$ argv对getopt()没有影响。我已经用这个脚本做了一些测试:
# t.php
<?php
var_dump($argv);
$argv = array();
var_dump($argv);
var_dump(getopt('a'));
?>
> php t.php -a
array(2) {
[0] =>
string(5) "t.php"
[1] =>
string(2) "-a"
}
array(0) {
}
array(1) {
'a' =>
bool(false)
}
所以,有适当的$ argv,我已经将它重写为空数组,仍然getopt()表现得没有任何反应。
问题:
答案 0 :(得分:1)
查看PHP源代码,当您调用(defun sum-rec (n)
(if (not (eq n 0))
(+ (sum-rec(- n 1)) n)
0))
> (format t "ans = ~A~%" (sum-rec 4))
ans = 10
时,似乎直接从Zend引擎检索argc
和argv
,因此更改全局变量不会影响其行为。您可以在此处查看getopt
的源代码:https://github.com/php/php-src/blob/master/ext/standard/basic_functions.c#L4264。
无论如何,我几乎可以肯定你无法改变这种意见。
答案 1 :(得分:0)
根据Gustavo的评论,我抛弃了getopt()并创建了我自己的自定义解析器。它是更大的代码库的一部分我无法在这里发布,因为它的代码太多了。我将发布相关方法,如果您需要这样的解决方案,我认为您将能够填补空白:
public function parse()
{
$i = 1;
$max = count($GLOBALS['argv'])-1;
while ($i <= $max) {
// Disallow arguments like '---any', '--s' and '-long'
$argName = $this->getArgumentName($GLOBALS['argv'][$i]);
if ($argName !== false) {
// Allow only previously defined arguments
if (\array_key_exists($argName, $this->args)) {
// Disallow arguments with empty values like '-s ""'
if (($i < $max) && $GLOBALS['argv'][$i+1]=='') {
throw new SyntaxException("Empty values are not allowed", SyntaxException::BAD_SYNTAX);
}
// if argument without value then set it to true
elseif ($i == $max || ($this->getArgumentName($GLOBALS['argv'][$i+1]) !== false)) {
$this->args[$argName]->setValue(true);
$i++;
}
// if argument with value then assign it the value
else {
$this->args[$argName]->setValue($GLOBALS['argv'][$i+1]);
$i+=2;
}
} else throw new SyntaxException("Unexpected argument `$argName`", SyntaxException::UNEXPECTED_ARGUMENT);
} else throw new SyntaxException("Wrong syntax of `{$GLOBALS['argv'][$i][0]}` argument", SyntaxException::BAD_SYNTAX);
}
return $this;
}
protected function getArgumentName($str)
{
$name = \preg_replace('/(?:^-([\w\d])$)|(?:^--([\w\d][\w\d_?!.:-]+)$)/', '$1$2', $str,1);
if (\is_null($name)) {
throw new LogicException("Error in regexp with `$str` string");
}
return ($str == $name) ? false : $name;
}
关于差距:这些异常不是来自SPL,它们是我的自定义异常层次结构。我这样做,以便异常代码也是脚本'返回代码。 此外,$ this-&gt; args是Argument类型对象的集合,能够保存参数类型/行为,名称,值,验证器等。