当前位置: 首页 > news >正文

symfony/console

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
============

相关文章:

symfony/console

github地址&#xff1a;GitHub - symfony/console: Eases the creation of beautiful and testable command line interfaces 文档地址&#xff1a;The Console Component (Symfony 5.4 Docs) 默认命令list&#xff0c;可以用register注册一个command命令&#xff0c;之后可以…...

OSI模型简介及socket,tcp,http三者之间的区别和原理

1.OSI模型简介&#xff08;七层网络模型&#xff09; OSI 模型(Open System Interconnection model)&#xff1a;一个由国际标准化组织提出的概念模型&#xff0c;试图提供一个使各种不同的计算机和网络在世界范围内实现互联的标准框架。 它将计算机网络体系结构划分为七层,每…...

【leetcode】leetcode69 x的平方根

文章目录 给你一个非负整数 x &#xff0c;计算并返回 x 的 算术平方根 。原理牛顿法&#xff08;数值分析中使用到的&#xff09;:二分法 解决方案java 实现实例执行结果 python 实现实例 给你一个非负整数 x &#xff0c;计算并返回 x 的 算术平方根 。 由于返回类型是整数&…...

springboot与rabbitmq的整合【演示5种基本交换机】

前言&#xff1a; &#x1f44f;作者简介&#xff1a;我是笑霸final&#xff0c;一名热爱技术的在校学生。 &#x1f4dd;个人主页&#xff1a;个人主页1 || 笑霸final的主页2 &#x1f4d5;系列专栏&#xff1a;后端专栏 &#x1f4e7;如果文章知识点有错误的地方&#xff0c;…...

【设计模式】设计原则-单一职责原则

单一职责原则 类的设计原则之单一职责原则&#xff0c;是最常用的类的设计的原则之一。 百度百科&#xff1a;就一个类而言&#xff0c;应该仅有一个引起它变化的原因。应该只有一个职责。 通俗的讲就是&#xff1a;一个类只做一件事 这个解释更通俗易懂&#xff0c;也更符…...

【C++】-多态的底层原理

&#x1f496;作者&#xff1a;小树苗渴望变成参天大树&#x1f388; &#x1f389;作者宣言&#xff1a;认真写好每一篇博客&#x1f4a4; &#x1f38a;作者gitee:gitee✨ &#x1f49e;作者专栏&#xff1a;C语言,数据结构初阶,Linux,C 动态规划算法&#x1f384; 如 果 你 …...

【部署】让你的电脑多出一个磁盘来用!使用SSHFS将远程服务器目录挂载到Windows本地,挂载并共享服务器资源

让你的电脑多出一个磁盘来用&#xff01;---使用SSHFS将远程服务器目录挂载到Windows本地 1. 方法原理介绍2.SSHFS-Win使用教程—实现远程服务器磁盘挂载本地 由于日常主要用 Windows 系统&#xff0c;每次都得 ssh 到服务器上进行取资源&#xff08;本地磁盘不富裕&#xff09…...

/var/lock/subsys目录的作用

总的来说&#xff0c;系统关闭的过程&#xff08;发出关闭信号&#xff0c;调用服务自身的进程&#xff09;中会检查/var/lock/subsys下的文件&#xff0c;逐一关闭每个服务&#xff0c;如果某一运行的服务在/var/lock/subsys下没有相应的选项。在系统关闭的时候&#xff0c;会…...

DETR (DEtection TRansformer)基于自建数据集开发构建目标检测模型超详细教程

目标检测系列的算法模型可以说是五花八门&#xff0c;不同的系列有不同的理论依据&#xff0c;DETR的亮点在于它是完全端到端的第一个目标检测模型&#xff0c;DETR&#xff08;Detection Transformer&#xff09;是一种基于Transformer的目标检测模型&#xff0c;由Facebook A…...

C++初阶 - 5.C/C++内存管理

目录 1.C/C的内存分布 2.C语言中动态内存管理方式&#xff1a;malloc、calloc、realloc、free 3.C内存管理方式 3.1 new/delete操作内置类型 3.2 new 和 delete操作自定义类型 4.operator new 与 operator delete 函数&#xff08;重要点&#xff09; 4.1 operator new 与…...

数学建模学习(3):综合评价类问题整体解析及分析步骤

一、评价类算法的简介 对物体进行评价&#xff0c;用具体的分值评价它们的优劣 选这两人其中之一当男朋友&#xff0c;你会选谁&#xff1f; 不同维度的权重会产生不同的结果 所以找到每个维度的权重是最核心的问题 0.25 二、评价前的数据处理 供应商ID 可靠性 指标2 指…...

【后端面经】微服务构架 (1-5) | 限流:濒临奔溃?限流守护者拯救系统于水火之中!

文章目录 一、前置知识1、什么是限流?2、限流算法A) 静态算法a) 漏桶b) 令牌桶c) 固定窗口d) 滑动窗口B) 动态算法3、限流的模式4、 限流对象4、限流后应该怎么做?二、面试环节1、面试准备2、基本思路3、亮点展现A) 突发流量(针对请求个数而言)B) 请求大小(针对请求大小而言)…...

HDFS异构存储详解

异构存储 HDFS异构存储类型什么是异构存储异构存储类型如何让HDFS知道集群中的数据存储目录是那种类型存储介质 块存储选择策略选择策略说明选择策略的命令 案例&#xff1a;冷热温数据异构存储对应步骤 HDFS内存存储策略支持-- LAZY PERSIST介绍执行使用 HDFS异构存储类型 冷…...

《面试1v1》Kafka消息是采用Pull还是Push模式

&#x1f345; 作者简介&#xff1a;王哥&#xff0c;CSDN2022博客总榜Top100&#x1f3c6;、博客专家&#x1f4aa; &#x1f345; 技术交流&#xff1a;定期更新Java硬核干货&#xff0c;不定期送书活动 &#x1f345; 王哥多年工作总结&#xff1a;Java学习路线总结&#xf…...

Windows环境Docker安装

目录 安装Docker Desktop的步骤 Docker Desktop 更新WSL WSL 的手动安装步骤 Windows PowerShell 拉取&#xff08;Pull&#xff09;镜像 查看已下载的镜像 输出"Hello Docker!" Docker Desktop是Docker官方提供的用于Windows的图形化桌面应用程序&#xff0c…...

Spring 6.0官方文档示例(23): singleton类型的bean和prototype类型的bean协同工作的方法(二)

使用lookup-method: 一、实体类&#xff1a; package cn.edu.tju.domain2;import java.time.LocalDateTime; import java.util.Map;public class Command {private Map<String, Object> state;public Map<String, Object> getState() {return state;}public void …...

Docker Compose 容器编排

Docker compose Docker compose 实现单机容器集群编排管理&#xff08;使用一个模板文件定义多个应用容器的启动参数和依赖关系&#xff0c;并使用docker compose来根据这个模板文件的配置来启动容器&#xff09; 通俗来说就是把之前的多条docker run启动容器命令 转换为docker…...

while循环

while循环是一种常见的循环结构&#xff0c;它会重复执行一段代码&#xff0c;直到指定的条件不再满足。 基本语法如下&#xff1a; while 条件: # 循环体代码 其中&#xff0c;条件是一个布尔表达式&#xff0c;如果为True&#xff0c;则执行循环体中的代码&#xff1b;如果…...

从JVM指令看String对象的比较

在翻看各类 java 知识中&#xff0c;总会提到如下知识&#xff1a;比较 String 对象&#xff0c;例如&#xff1a; String a1new String("10"); String a2"10"; String a3"1""0";//结果 System.out.println(a1a2); //false System.ou…...

python与深度学习(六):CNN和手写数字识别二

目录 1. 说明2. 手写数字识别的CNN模型测试2.1 导入相关库2.2 加载数据和模型2.3 设置保存图片的路径2.4 加载图片2.5 图片预处理2.6 对图片进行预测2.7 显示图片 3. 完整代码和显示结果4. 多张图片进行测试的完整代码以及结果 1. 说明 本篇文章是对上篇文章训练的模型进行测试…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略

本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装&#xff1b;只需暴露 19530&#xff08;gRPC&#xff09;与 9091&#xff08;HTTP/WebUI&#xff09;两个端口&#xff0c;即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

return this;返回的是谁

一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请&#xff0c;不同级别的经理有不同的审批权限&#xff1a; // 抽象处理者&#xff1a;审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

Caliper 配置文件解析:fisco-bcos.json

config.yaml 文件 config.yaml 是 Caliper 的主配置文件,通常包含以下内容: test:name: fisco-bcos-test # 测试名称description: Performance test of FISCO-BCOS # 测试描述workers:type: local # 工作进程类型number: 5 # 工作进程数量monitor:type: - docker- pro…...

解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist

现象&#xff1a; android studio报错&#xff1a; [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决&#xff1a; 不要动CMakeLists.…...

【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error

在前端开发中&#xff0c;JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作&#xff08;如 Promise、async/await 等&#xff09;&#xff0c;开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝&#xff08;r…...

认识CMake并使用CMake构建自己的第一个项目

1.CMake的作用和优势 跨平台支持&#xff1a;CMake支持多种操作系统和编译器&#xff0c;使用同一份构建配置可以在不同的环境中使用 简化配置&#xff1a;通过CMakeLists.txt文件&#xff0c;用户可以定义项目结构、依赖项、编译选项等&#xff0c;无需手动编写复杂的构建脚本…...

HTML前端开发:JavaScript 获取元素方法详解

作为前端开发者&#xff0c;高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法&#xff0c;分为两大系列&#xff1a; 一、getElementBy... 系列 传统方法&#xff0c;直接通过 DOM 接口访问&#xff0c;返回动态集合&#xff08;元素变化会实时更新&#xff09;。…...

DeepSeek源码深度解析 × 华为仓颉语言编程精粹——从MoE架构到全场景开发生态

前言 在人工智能技术飞速发展的今天&#xff0c;深度学习与大模型技术已成为推动行业变革的核心驱动力&#xff0c;而高效、灵活的开发工具与编程语言则为技术创新提供了重要支撑。本书以两大前沿技术领域为核心&#xff0c;系统性地呈现了两部深度技术著作的精华&#xff1a;…...