升级后容器依赖报错源于topthink/framework 6.1重构服务容器注入机制,导致未适配的扩展或自定义服务在调用时机、绑定方式及延迟加载上不兼容。

升级后出现容器依赖报错,基本可以断定是 topthink/framework 6.1 版本对服务容器的注入机制做了重构,而你项目里某个扩展或自定义服务没适配——不是代码写错了,是调用时机或绑定方式变了。
为什么 App::make() 突然找不到类或报“Circular reference”
6.1 开始强化容器的“延迟绑定”和“作用域隔离”,App::make() 不再无条件从全局容器取实例,尤其当类依赖了 Request、Response 或其他运行时上下文对象时,会触发循环引用检测。旧版 TP6.0.x 允许在容器初始化阶段就 resolve 这些对象,6.1 拦住了。
- 常见错误现象:
Circular reference detected for service "think\Request"或Class not found: app\service\UserService(但文件明明存在) - 根本原因:你在
app/provider.php或config/app.php的providers数组里直接 new 了一个带依赖的类,或者用了App::bind()绑定了一个已实例化的对象,而不是闭包 - 正确做法:所有需要运行时上下文的服务,必须用闭包延迟注册,例如:
App::bind('UserService', function () { return new \app\service\UserService(\think\facade\Request::instance()); }); - 别把
App::make('think\Request')放在 provider 初始化里——它还没准备好;改用app('request')或等中间件之后再调
think-swoole 和 think-queue 这类扩展报“Cannot use object of type Closure as array”
这是典型的扩展未适配 6.1 容器返回值类型变更。6.1 中 Container::get() 对闭包绑定项不再自动执行,而是返回 Closure 实例本身;老扩展还按旧逻辑把它当数组解构,就崩了。
- 检查你装的扩展版本:运行
composer show think-swoole,确认是否 ≥ 3.2.0(支持 TP6.1);think-queue需 ≥ 4.1.0 - 如果版本够但还报错,大概率是你本地锁了旧版:删掉
composer.lock和vendor,再跑composer install - 临时绕过:在
config/swoole.php或config/queue.php中,把原本写成'handler' => \app\queue\JobHandler::class的地方,改成'handler' => function () { return new \app\queue\JobHandler(); }
升级后 config/app.php 里的 providers 数组全失效
TP6.1 把服务提供者加载逻辑从「静态数组遍历」改成了「事件驱动 + 条件注册」,providers 数组只在应用启动早期生效,且跳过所有含 isDeferred() 返回 true 的 provider——很多第三方扩展默认启用了延迟加载,结果被跳过了。
立即学习“PHP免费学习笔记(深入)”;
- 验证方法:在任意控制器里加一行
var_dump(app()->getProviders());,看输出是否为空或明显缺几个 - 解决路径:不要依赖 config 数组自动加载,显式在
app/bootstrap.php或public/index.php启动后手动注册,例如:app()->register(new \think\swoole\provider\SwooleProvider()); - 注意顺序:SwooleProvider 必须在 AppServiceProvider 之后注册,否则
$this->app是 null - 如果你用了多应用模式,
app/multi-app/bootstrap.php里的 provider 注册也要同步检查,6.1 不再自动扫描子应用下的 provider
最常被忽略的一点:6.1 要求所有服务提供者的 register() 方法必须是 public,且不能有参数——哪怕你只是加了个 array $options = [],容器就会静默跳过它,不报错也不注册。



















