Slim CLI 集成需复用同一容器实例,命令类须按 PSR-4 注册到 settings['commands'] 并实现 Symfony Command 接口,通过 $this->getApplication()->getContainer() 获取服务,避免构造函数依赖 Request/Response。

Slim 默认不支持 CLI,必须手动集成容器和命令调度逻辑,否则 php bin/console test 会报 Class not found 或 Container has no entry 错误。
CLI 脚本入口必须复用 Slim 容器实例
直接 new 一个新 App 或空容器会导致路由、中间件、配置全部失效。CLI 命令需要访问数据库连接、日志实例、缓存等——这些都得从同一个容器里取。
- 把
bootstrap/app.php(或你项目里初始化容器的主文件)里的容器创建逻辑抽出来,确保它可被 CLI 脚本 require -
bin/console文件开头必须包含:require __DIR__ . '/../bootstrap/app.php';,然后调用$container->get('settings')['commands']获取已注册命令列表 - 不要在 CLI 脚本里重复调用
$app->run(),它只处理 HTTP 生命周期,CLI 场景下完全不需要
命令类必须按 PSR-4 自动加载且显式注册到容器
哪怕类文件存在、命名规范、composer dump-autoload 也执行了,如果没在容器设置里声明,Slim 就不知道该加载哪个类。
- 在
settings数组中加一项:'commands' => ['test' => \Console\TestCommand::class] -
Console/TestCommand.php必须实现Symfony\Component\Console\Command\Command接口(注意不是 Slim 自带的) - 类内部的
configure()和execute()方法里,可通过$this->getApplication()->getContainer()拿到 Slim 容器,避免全局变量或重新 new 实例
PSR-7 实现与 CLI 兼容性无关,但 nyholm/psr7 更省心
CLI 不走 HTTP 请求响应流,所以 nyholm/psr7、slim/psr7、httpsoft/http-message 对 CLI 功能本身没影响。但选 nyholm/psr7 可避免某些旧版 Symfony Console 在调试时意外触发 PSR-7 构造逻辑的问题。
立即学习“PHP免费学习笔记(深入)”;
- 如果你已在项目中用了
nyholm/psr7,CLI 脚本里无需额外 require 或初始化它 - 别在 CLI 脚本里调用
ServerRequest::fromGlobals()—— 这个方法依赖$_SERVER,CLI 下为空,会抛InvalidArgumentException - 真正要验证的是:运行
php bin/console list能否输出你的命令名,而不是看有没有 PSR-7 报错
常见错误:命令执行后退出码为 1 但无提示
这通常是因为命令类的 execute() 方法没显式返回整数,或者抛出了未捕获的异常(比如数据库连接失败但没 try/catch)。
- 确保
execute()最后一行是return 0;(成功)或return 1;(失败) - 在
execute()开头加try { ... } catch (\Exception $e) { $io->error($e->getMessage()); return 1; },否则错误会被吞掉 - 别依赖
echo输出结果,用$io->writeln('Done')($io是Symfony\Component\Console\Style\SymfonyStyle实例)
最易被忽略的一点:CLI 命令类的构造函数里不能直接依赖 Request 或 Response 类型提示——它们在 CLI 环境下无法解析,容器注入会失败。需要改用延迟获取,比如在 execute() 里通过容器 get 实例。



















