Symfony控制台命令的参数需通过$input->getArgument()和$input->getOption()在execute()中手动获取,不可在构造函数中保存InputInterface或OutputInterface对象,所有I/O操作必须在execute()内完成。
命令参数怎么传给
类的
方法
Symfony 控制台命令的参数不是自动塞进
的,得靠
对象手动取。很多人写完
加了
或
,却在
里直接用变量名访问,结果报
或始终拿不到值。
取位置参数(如
中的
)
取选项参数(如
或
)
参数名必须和
里定义的一致,大小写敏感
未设默认值又没传入的必填参数(
)会导致命令直接报错退出,不会进
和
能不能在构造函数里存起来
不能。这两个对象是每次命令执行时新实例化的,生命周期只限于单次调用。如果在
里保存
或
,下次运行命令会用到旧引用,极大概率触发
这类错误,或者输出乱序、缓冲失效。
所有输入读取、输出写入操作,必须在
内完成
需要复用逻辑?把处理函数抽成私有方法,把
和
当参数传进去
想提前校验参数?用
判断选项是否存在,别依赖构造时的状态
输出中文或特殊字符时乱码、换行失效
根本原因不是 Symfony,而是终端编码或 PHP 输出缓冲配置。Symfony 默认用
的
和
,它们不主动处理字符集转换,直接交给底层
流。
确保终端支持 UTF-8(Linux/macOS 一般没问题;Windows CMD 需先执行
)
避免在
开头用
或
,会绕过
的格式控制,导致颜色、缩进、进度条异常
要输出带样式的文本,用
,别拼接 ANSI 转义序列
大段日志建议用
关闭自动换行,自己控制输出节奏
为什么
返回 null 却不报错
因为参数定义时没设为必填,且没给默认值。Symfony 不会在运行时强制校验可选参数的存在性,它只按定义返回
—— 这个行为容易被当成“没传对”,实际是设计如此。
检查
中是否用了
(默认就是它)
需要非空保障?用
更稳妥的方式:在
里明确写
,让框架在入口就拦截
注意:
和
都不会抛异常,null 就是“没提供”的信号
命令真正难的不是写法,是理解
和
是单次请求上下文对象,不是全局服务。一不留神就拿它们当状态容器用,后面调试半天才发现是引用错位。
Commandexecute()execute()$inputconfigure()addArgument()addOption()execute()Undefined variable$input->getArgument('name')php bin/console app:deploy prodprod$input->getOption('force')--force-fconfigure()InputArgument::REQUIREDexecute()InputInterfaceOutputInterface__construct()$input$outputCannot use object of type Symfony\Component\Console\Input\ArgvInput as arrayexecute()$input$output$input->hasParameterOption()OutputInterfacewrite()writeln()stdoutchcp 65001execute()echoprintOutputInterface$output->writeln('成功 ')$output->write($text, false)$input->getArgument()nullconfigure()InputArgument::OPTIONAL$input->getArgument('path') ?: throw new \RuntimeException('缺少 --path 参数')configure()->setRequired(true)getArgument()getOption()InputInterfaceOutputInterface