直接执行 composer require symfony/console 即可,该组件独立于全栈框架,Composer 自动适配 PHP 版本;需手动创建 bin/console 入口并赋予可执行权限;命令类必须继承 Command、调用 setName()、被显式 add();参数用 argument、配置用 option,交互输入须按语义选用对应方法。

直接执行 composer require symfony/console 就行,别找 Console_Composer
根本不存在叫 Console_Composer 的包——所有搜到的结果都是命名混淆或过时信息。你要的只是 symfony/console 这个独立组件,它不依赖 Symfony 全栈框架,装完就能用。Composer 会根据你项目声明的 PHP 版本自动选兼容版本:php ^8.1 装 v6.4,php ^7.4 则 fallback 到 ^5.4。常见报错 Root composer.json requires symfony/console ^6.0, found ... but these were not loaded,八成是因为 composer.json 里写了过高的 "config": {"platform": {"php": "8.2.0"}},而本地实际是 PHP 8.0,删掉或改对再 composer update 即可。
bin/console 不会自动生成,漏了它就 Could not open input file
装完 symfony/console 只是引入类库,不会创建任何文件。必须手动建入口脚本,否则连 php bin/console list 都跑不起来。最简可用的 bin/console 长这样:
#!/usr/bin/env php <?php require __DIR__.'/../vendor/autoload.php'; use Symfony\Component\Console\Application; $application = new Application(); $application->run();
注意三点:
-
chmod +x bin/console—— 缺少可执行权限,./bin/console会报 Permission denied -
require路径必须是../vendor/autoload.php,写成vendor/autoload.php或绝对路径都不可移植 - 别把命令逻辑写进这个文件——它只负责启动
Application,业务全扔到 Command 类里
命令类必须同时满足三个硬性条件,缺一不可
哪怕代码看着全对,只要漏一条,app:do-something 就不会出现在 list 输出里。检查这三项:
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
- 类必须
extends Symfony\Component\Console\Command\Command,不能只是普通class - 必须在
configure()里调用$this->setName('app:do-something')——$defaultName静态属性只是快捷写法,底层仍靠setName()注册 - 入口文件中要显式
$application->add(new App\Command\DoSomethingCommand()),symfony/console 不扫描目录,不支持自动发现
返回值也得是整数:return Command::SUCCESS(=0)或 Command::FAILURE(≠0)。用 exit(0) 看似能跑通,但管道调用(如 mycmd | grep foo)和单元测试会直接崩。
参数用 argument,配置用 option,语义错了后续全是坑
把 --env=prod 写成必需 argument(如 myapp deploy prod),会导致无法设默认值、帮助文档误导用户、组合调用困难。记住:
-
argument是位置型、无前缀、适合核心操作对象,比如user:delete <id></id>中的<id></id> -
option是键值型、带--或-前缀、适合开关或上下文,比如--force、--timeout=30 - 必需 argument 只能靠
InputArgument::REQUIRED(默认),但一旦要支持默认值或可选,就得换InputArgument::OPTIONAL,不如直接用option清晰
交互输入也一样:密码用 askHiddenResponse(),确认用 confirm(),选项列表用 choice() —— 它们底层处理回显、中断、空值的方式完全不同,混用会暴露敏感信息或跳过确认。

















