webman 默认禁用自动依赖注入,需手动接入 php-di 并返回 psr-11 容器实例;必须调用 useautowiring(true) 和 useattributes(true) 才支持构造函数与 #[inject] 注入;闭包路由中 new 实例绕过容器,应改用数组路由或 container::get()。

Webman 默认不启用自动依赖注入,所有构造函数参数、属性注解、#[Inject] 都不会生效——这不是 bug,是设计选择;想用 DI,必须手动接入 php-di 并正确配置容器实例。
config/container.php 返回的必须是 PSR-11 容器实例
框架启动时会把 config/container.php 的返回值传给 Webman\App 构造函数,该参数类型限定为 Psr\Container\ContainerInterface。返回一个裸对象(比如 new Webman\Container())或空数组,会直接报错:Argument 1 passed to Webman\App::__construct() must implement interface Psr\Container\ContainerInterface。
- 正确做法:用
DI\ContainerBuilder构建并调用->build(),确保最终返回的是DI\Container实例 - 错误写法:
return ['db' => new PDO(...)];或return new StdClass();都会中断启动 - 若你用其他容器(如
league/container),也必须确认它实现了Psr\Container\ContainerInterface
useAutowiring(true) 和 useAttributes(true) 必须显式开启
php-di 默认关闭自动解析,即使装了包、写了 ->build(),不调这两个方法,__construct(Database $db) 里的 $db 依然不会被注入,只会报 Entry "App\Service\X" cannot be resolved。
Webman 2.2.0版本强化了 TCP/UDP 服务支持,优化路由组管理,并增强异步任务处理能力。结合协程与连接池技术,Webman 能轻松应对高并发场景,适用于网站、接口服务、即时通讯、物联网及游戏开发,兼具高性能、灵活扩展与稳定可靠,是多场景 PHP 服务开发的理想选择。
-
$builder->useAutowiring(true)启用基于类型提示的构造函数参数自动解析 -
$builder->useAttributes(true)才支持 PHP 8+ 的#[Inject]属性注入(注意:不是@Inject注释) - 二者缺一不可;只开
useAutowiring但没写构造函数参数类型,照样失败
闭包路由中 new 实例完全绕过容器
写 Route::get('/user', fn() => new UserController()) 这种代码,无论容器配得多完美,UserController 都不会被注入任何依赖,PHP 8+ 下还会因未初始化 typed property 报错:Typed property app\controller\UserController::$mailer must not be accessed before initialization。
- 根本原因:这是纯 PHP
new,不经过框架容器生命周期 - 正确替代:改用数组路由
[UserController::class, 'index'],或在闭包里用Container::get(UserController::class) - 中间件中若需手动创建服务实例,推荐用
Container::make($class, [$request])而非new,避免Request对象丢失
接口绑定必须显式加载且路径可扫描
如果定义了 LoggerInterface::class => FileLogger::class 这类绑定,但容器没“看见” FileLogger 类,注入仍会失败。常见原因是 config/dependence.php 没被 $builder->addDefinitions() 加载,或类文件不在自动加载路径里。
- 确认
config/container.php中调用了$builder->addDefinitions(config('dependence', [])) - 检查
config/dependence.php是否存在,且返回的是键值对数组,不是空或 null - 若使用匿名类、动态构造参数、魔术方法(如
__call),php-di可能无法解析依赖树,报错晦涩,建议改用显式app()->get()替代自动注入
真正容易被忽略的点在于:DI 不是“配完就能用”,而是“配对了才开始工作”。哪怕只漏掉一行 useAutowiring(true),或者路由写成闭包 new,整个注入链就断了——它不会报语法错,而是在运行时抛出看似无关的初始化异常。










