symfony/console

news/2024/10/23 9:26:44/

github地址:GitHub - symfony/console: Eases the creation of beautiful and testable command line interfaces

文档地址:The Console Component (Symfony 5.4 Docs)

默认命令list,可以用register注册一个command命令,之后可以设置其他内容,或者设置命令类再加到框架中。

#Symfony\Component\Console\Application
public function __construct(string $name = 'UNKNOWN', string $version = 'UNKNOWN'){$this->name = $name;$this->version = $version;$this->terminal = new Terminal();$this->defaultCommand = 'list';if (\defined('SIGINT') && SignalRegistry::isSupported()) {$this->signalRegistry = new SignalRegistry();$this->signalsToDispatchEvent = [\SIGINT, \SIGTERM, \SIGUSR1, \SIGUSR2];}}
public function register(string $name){return $this->add(new Command($name));}
public function add(Command $command){……$this->commands[$command->getName()] = $command;……}#Symfony\Component\Console\Command\Command
//设置执行代码
public function setCode(callable $code){if ($code instanceof \Closure) {$r = new \ReflectionFunction($code);if (null === $r->getClosureThis()) {set_error_handler(static function () {});try {if ($c = \Closure::bind($code, $this)) {$code = $c;}} finally {restore_error_handler();}}}$this->code = $code;return $this;}
//设置命令名
public function setName(string $name){$this->validateName($name);$this->name = $name;return $this;}
//设置别名public function setAliases(iterable $aliases){$list = [];foreach ($aliases as $alias) {$this->validateName($alias);$list[] = $alias;}$this->aliases = \is_array($aliases) ? $aliases : $list;return $this;}
//设置帮助内容
public function setHelp(string $help){$this->help = $help;return $this;}
//设置是否隐藏
public function setHidden(bool $hidden /* = true */){$this->hidden = $hidden;return $this;}
//设置描述
public function setDescription(string $description){$this->description = $description;return $this;}
#运行文件
require __DIR__ . '/vendor/autoload.php';
require __DIR__ . '/Test1Command.php';use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;$application = new Application();
$application->register('test')->addArgument('username', InputArgument::REQUIRED, '用户名')->addOption('pwd', "P", InputArgument::REQUIRED, '密码')->setDescription("test command")->setCode(function (InputInterface $input, OutputInterface $output) {return Command::SUCCESS;});
$test1command = new Test1Command();
$application->add($test1command);
$application->run();#Test1Command
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;class Test1Command extends Command
{protected function configure(){$this->setName("test1");$this->setHelp('This command allows you to create a user...');$this->addArgument('test', InputArgument::REQUIRED, 'test');$this->setDescription("test1 command");}protected function execute(InputInterface $input, OutputInterface $output): int{var_dump($input->getArguments());//$listcommand = $this->getApplication()->get('list');//$listcommand->run($input, $output);$input = new ArrayInput(['command' => 'list']);$listcommand = $this->getApplication()->get('list');$listcommand->run($input, $output);$output->writeln(['Test1 Command','============','',]);return Command::SUCCESS;}
}

InputInterface实体类为Symfony\Component\Console\Input\ArgvInput,该类继承Symfony\Component\Console\Input\Input,会校验参数和用于获取参数。

#Symfony\Component\Console\Application
public function run(InputInterface $input = null, OutputInterface $output = null){if (\function_exists('putenv')) {@putenv('LINES=' . $this->terminal->getHeight());@putenv('COLUMNS=' . $this->terminal->getWidth());}if (null === $input) {//默认input$input = new ArgvInput();}if (null === $output) {//默认输出$output = new ConsoleOutput();}……$exitCode = $this->doRun($input, $output);……}
public function doRun(InputInterface $input, OutputInterface $output){$input->bind($this->getDefinition());……$name = $this->getCommandName($input);……if (!$name) {$name = $this->defaultCommand;$definition = $this->getDefinition();$definition->setArguments(array_merge($definition->getArguments(),['command' => new InputArgument('command', InputArgument::OPTIONAL, $definition->getArgument('command')->getDescription(), $name),]));}……try {$this->runningCommand = null;// the command name MUST be the first element of the input$command = $this->find($name);} catch (\Throwable $e) {……$alternatives = $e->getAlternatives();……$alternative = $alternatives[0];……$command = $this->find($alternative);}if ($command instanceof LazyCommand) {$command = $command->getCommand();}$this->runningCommand = $command;$exitCode = $this->doRunCommand($command, $input, $output);$this->runningCommand = null;return $exitCode;}#Symfony\Component\Console\Exception\CommandNotFoundException
class CommandNotFoundException extends \InvalidArgumentException implements ExceptionInterface
{private $alternatives;/*** @param string          $message      Exception message to throw* @param string[]        $alternatives List of similar defined names* @param int             $code         Exception code* @param \Throwable|null $previous     Previous exception used for the exception chaining*/public function __construct(string $message, array $alternatives = [], int $code = 0, \Throwable $previous = null){parent::__construct($message, $code, $previous);$this->alternatives = $alternatives;}/*** @return string[]*/public function getAlternatives(){return $this->alternatives;}
}#Symfony\Component\Console\Input\Input
public function __construct(InputDefinition $definition = null){if (null === $definition) {$this->definition = new InputDefinition();} else {//校验选项$this->bind($definition);//校验参数$this->validate();}}
//校验参数
public function validate(){$definition = $this->definition;$givenArguments = $this->arguments;$missingArguments = array_filter(array_keys($definition->getArguments()), function ($argument) use ($definition, $givenArguments) {return !\array_key_exists($argument, $givenArguments) && $definition->getArgument($argument)->isRequired();});if (\count($missingArguments) > 0) {throw new RuntimeException(sprintf('Not enough arguments (missing: "%s").', implode(', ', $missingArguments)));}}
//获取所有参数
public function getArguments(){return array_merge($this->definition->getArgumentDefaults(), $this->arguments);}
//根据变量名获取参数
public function getArgument(string $name){if (!$this->definition->hasArgument($name)) {throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));}return $this->arguments[$name] ?? $this->definition->getArgument($name)->getDefault();}
//设置参数值public function setArgument(string $name, $value){if (!$this->definition->hasArgument($name)) {throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name));}$this->arguments[$name] = $value;}
//判断是否有参数
public function hasArgument(string $name){return $this->definition->hasArgument($name);}
//获取全部选项public function getOptions(){return array_merge($this->definition->getOptionDefaults(), $this->options);}
//根据名称获取选项值
public function getOption(string $name){if ($this->definition->hasNegation($name)) {if (null === $value = $this->getOption($this->definition->negationToName($name))) {return $value;}return !$value;}if (!$this->definition->hasOption($name)) {throw new InvalidArgumentException(sprintf('The "%s" option does not exist.', $name));}return \array_key_exists($name, $this->options) ? $this->options[$name] : $this->definition->getOption($name)->getDefault();}
//设置选项值
public function setOption(string $name, $value){if ($this->definition->hasNegation($name)) {$this->options[$this->definition->negationToName($name)] = !$value;return;} elseif (!$this->definition->hasOption($name)) {throw new InvalidArgumentException(sprintf('The "%s" option does not exist.', $name));}$this->options[$name] = $value;}
//判断是否有选项值
public function hasOption(string $name){return $this->definition->hasOption($name) || $this->definition->hasNegation($name);}#Symfony\Component\Console\Input\ArgvInput
protected function parse(){$parseOptions = true;$this->parsed = $this->tokens;while (null !== $token = array_shift($this->parsed)) {$parseOptions = $this->parseToken($token, $parseOptions);}}
protected function parseToken(string $token, bool $parseOptions): bool{if ($parseOptions && '' == $token) {$this->parseArgument($token);} elseif ($parseOptions && '--' == $token) {return false;} elseif ($parseOptions && str_starts_with($token, '--')) {$this->parseLongOption($token);} elseif ($parseOptions && '-' === $token[0] && '-' !== $token) {$this->parseShortOption($token);} else {$this->parseArgument($token);}return $parseOptions;}
private function parseShortOption(string $token){$name = substr($token, 1);if (\strlen($name) > 1) {if ($this->definition->hasShortcut($name[0]) && $this->definition->getOptionForShortcut($name[0])->acceptValue()) {// an option with a value (with no space)$this->addShortOption($name[0], substr($name, 1));} else {$this->parseShortOptionSet($name);}} else {$this->addShortOption($name, null);}}private function addShortOption(string $shortcut, $value){if (!$this->definition->hasShortcut($shortcut)) {throw new RuntimeException(sprintf('The "-%s" option does not exist.', $shortcut));}$this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value);}

运行

 php test.php test 123
php test.php test --helpDescription:test commandUsage:test [options] [--] <username>Arguments:username              用户名Options:-P, --pwd             密码-h, --help            Display help for the given command. When no command is given display help for the list command-q, --quiet           Do not output any message-V, --version         Display this application version--ansi|--no-ansi  Force (or disable --no-ansi) ANSI output-n, --no-interaction  Do not ask any interactive question-v|vv|vvv, --verbose  Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debugHelp:123
php test.php test1 --helpDescription:test1 commandUsage:test1 <test>Arguments:test                  testOptions:-h, --help            Display help for the given command. When no command is given display help for the list command-q, --quiet           Do not output any message-V, --version         Display this application version--ansi|--no-ansi  Force (or disable --no-ansi) ANSI output-n, --no-interaction  Do not ask any interactive question-v|vv|vvv, --verbose  Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debugHelp:This command allows you to create a user...
php test.php test1 111array(2) {'command' =>string(5) "test1"'test' =>string(3) "111"
}
Console ToolUsage:command [options] [arguments]Options:-h, --help            Display help for the given command. When no command is given display help for the list command-q, --quiet           Do not output any message-V, --version         Display this application version--ansi|--no-ansi  Force (or disable --no-ansi) ANSI output-n, --no-interaction  Do not ask any interactive question-v|vv|vvv, --verbose  Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debugAvailable commands:completion  Dump the shell completion scripthelp        Display help for a commandlist        List commandstest        test commandtest1       test1 command
Test1 Command
============


http://www.ppmy.cn/news/982072.html

相关文章

20种常用的软件测试方法,建议先收藏再观看

软件测试在完整的项目当中算是最后一个环节&#xff0c;也是非常重要的一个环节。通过软件测试&#xff0c;我们才能得知一个程序是否符合标准。 小编整理出20种常见的软件测试方法&#xff0c;建议伙伴们先收藏再看。不敢说史上最全&#xff0c;但我办公室里十年软件测试经验…

uniapp WIFI上下班打卡

大纲 &#x1f959; uniapp官网&#xff1a;uni-app官网 &#x1f959; WIFI功能模块&#xff1a; 1、下载 wifi 插件 uni-WiFi 2、在 manifest.json 中 App权限配置中 配置权限 1. ACCESS_WIFI_STATE &#xff08;访问权限状态&#xff09; 2. CHANGE_WIFI_STATE&#xff…

慕课网Go——1.go语言基础

3. 变量 3.1 定义变量 package mainimport "fmt"// 全局变量可以不使用 var flg boolfunc main() {//局部变量定义后必须使用&#xff0c;默认零值var name int 1fmt.Println(name)age : 1fmt.Println(age)//多变量定义&#xff0c;可以不同类型var s1, s2 "…

RL 实践(5)—— 二维滚球环境【REINFORCE Actor-Critic】

本文介绍如何用 REINFORCE 和 Actor-Critic 这两个策略梯度方法解二维滚球问题参考&#xff1a;《动手学强化学习》完整代码下载&#xff1a;6_[Gym Custom] RollingBall (REINFORCE and Actor-Critic) 文章目录 1. 二维滚球环境2. 策略梯度方法2.1 策略学习目标2.2 策略梯度定…

IIS部署安装.NET CORE6.0应用程序,成功解决http error 503.the service is unavailable错误

一、下载安装.NET CORE 运行环境包 网址&#xff1a;Download .NET Core 3.1 (Linux, macOS, and Windows).NET Core 3.1 downloads for Linux, macOS, and Windows. .NET is a free, cross-platform, open-source developer platform for building many different types of ap…

13.Netty源码之Netty中的类与API

highlight: arduino-light ServerBootstrap Bootstrap 意思是引导&#xff0c;一个 Netty 应用通常由一个 Bootstrap 开始&#xff0c;主要作用是配置整个 Netty 程序&#xff0c;串联各个组件&#xff0c;Netty 中ServerBootstrap 是服务端启动引导类。 java //泛型 AbstractB…

vue指令-v-on事件对象

vue指令-v-on事件对象 1、目的2、语法 1、目的 vue事件处理函数中&#xff0c;拿到事件对象 2、语法 无传参数&#xff0c;通过形参直接接收 <template><div id"app"><a click"one" href"http://www.baidu.com">百度</…

IDEA插件YapiUpload配置YApi

前后端分离开发项目&#xff0c;后端提供接口文档&#xff0c;这次使用的是YApi&#xff0c;不想一个个接口添加&#xff0c;所以用插件批量导入。 YApi 是高效、易用、功能强大的 api 管理平台&#xff0c;旨在为开发、产品、测试人员提供更优雅的接口管理服务。可以帮助开发…