framework
framework copied to clipboard
Input类hasArgument()和hasOption()处理不一致
我使用TP6.0.12创建自定义的命令HelloCommand:
<?php
declare (strict_types = 1);
namespace app\command;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
class HelloCommand extends Command
{
protected function configure()
{
$this->setName('hello')
->setDescription('Hello command')
->addArgument('name', Argument::OPTIONAL, "your name")
->addOption('city', null, Option::VALUE_REQUIRED, 'city name');
}
protected function execute(Input $input, Output $output)
{
$name = trim($input->getArgument('name')) ?: 'thinkphp';
if ($input->hasOption('city')) {
$city = PHP_EOL . 'From ' . $input->getOption('city');
} else {
$city = '';
}
$output->writeln("Hello, " . $name . '!' . $city);
}
}
当执行如下命令时
php think hello
提示如下的错误信息
[TypeError]
trim() expects parameter 1 to be string, null given
Exception trace:
() at D:\PHPSTUDY\WWW\thinkphp6\app\command\HelloCommand.php:25
trim() at D:\PHPSTUDY\WWW\thinkphp6\app\command\HelloCommand.php:25
app\command\HelloCommand->execute() at D:\PHPSTUDY\WWW\thinkphp6\vendor\topthink\framework\src\think\console\Command.php:210
think\console\Command->run() at D:\PHPSTUDY\WWW\thinkphp6\vendor\topthink\framework\src\think\Console.php:655
think\Console->doRunCommand() at D:\PHPSTUDY\WWW\thinkphp6\vendor\topthink\framework\src\think\Console.php:314
think\Console->doRun() at D:\PHPSTUDY\WWW\thinkphp6\vendor\topthink\framework\src\think\Console.php:251
think\Console->run() at D:\PHPSTUDY\WWW\thinkphp6\think:10
我查了Input类这两个方法的实现方式,发现hasArgument()方法的实现与hasOption()不同。 hasArgument()方法取消isset($this->arguments)的检查,这样才能确保有CLI有提供值时才会返回true。
/**
* 检查是否存在某个参数
* @param string|int $name 参数名或位置
* @return bool
*/
public function hasArgument($name): bool
{
return $this->definition->hasArgument($name);
}
/**
* 是否有某个选项
* @param string $name 选项名
* @return bool
*/
public function hasOption(string $name): bool
{
return $this->definition->hasOption($name) && isset($this->options[$name]);
}