Webman 默认不启用自动依赖注入,需显式配置 php-di;闭包路由中 new 实例绕过容器导致 typed property 报错,应改用数组路由或 Container::get;PHP 8+ 属性注入存在时机风险,推荐构造函数注入。

Webman 默认不启用自动依赖注入,必须显式配置 php-di 才能用构造函数或属性注入——否则 private Mailer $mailer 会直接报错 Typed property must not be accessed before initialization。
闭包路由里根本没法用自动注入
Route::get('/test', fn() => new UserController()) 这类写法完全绕过容器,php-di 压根没机会解析依赖。哪怕 config/container.php 配得再全也没用。
- 错误现象:访问时抛出
Typed property app\controller\UserController::$mailer must not be accessed before initialization - 根本原因:闭包中
new UserController()是纯 PHP 实例化,不走框架容器流程 - 正确做法:改用控制器数组路由
Route::get('/test', [UserController::class, 'index']),或在闭包内手动调用Container::get(UserController::class)
PHP 8+ 的 typed property 必须搭配构造函数注入
private Mailer $mailer 这种写法在 PHP 8+ 中要求属性在读取前已被赋值,而 php-di 的属性注入是对象创建后通过反射写入,存在时机风险。
Webman 2.2.0版本强化了 TCP/UDP 服务支持,优化路由组管理,并增强异步任务处理能力。结合协程与连接池技术,Webman 能轻松应对高并发场景,适用于网站、接口服务、即时通讯、物联网及游戏开发,兼具高性能、灵活扩展与稳定可靠,是多场景 PHP 服务开发的理想选择。
- 注解注入(
@Inject)在构造函数执行完、方法调用前可能还没完成赋值 - 若在
__construct()末尾就调用$this->mailer->send(),必报错 - 临时缓解可改成
private ?Mailer $mailer = null,但生产环境建议直接用构造函数注入 - 确认你装的是
php-di/php-di:^7.0,低版本不支持 PHP 8 属性注入
手动 new 的实例永远得不到注入
只要用了 new UserService(),无论容器怎么配,这个实例都不会被注入任何依赖——这是设计使然,不是 bug。
- 需要无参实例:用
Container::get(UserService::class) - 需要传参实例:用
Container::make(LogService::class, [$path, $name]) - 第三方回调中无法用容器?那就别让那个类承担依赖职责,把
$mailer当作方法参数传进去 - 混用
new和Container::get()会导致依赖链断裂,测试和替换都会变困难
config/container.php 配错一个字母就失效
这个文件最终必须返回一个 PSR-11 兼容的容器实例,常见错误是漏掉 return 或返回了数组。
- 正确写法结尾必须是
return $builder->build();,不能是return new Container();(webman 自带容器不支持自动注入) - 启用注解需加
$builder->useAttributes(true),否则@Inject被忽略 - 启用自动装配需加
$builder->useAutowiring(true),否则构造函数参数不会被递归解析 - 服务定义放在
config/dependence.php,不是container.php;该文件不存在也不会报错,只是没自定义绑定
最易被忽略的一点:php-di 的注入只对框架主动创建的对象生效(控制器、中间件、事件监听器),它不会、也不能去劫持你代码里每一处 new。依赖注入不是全局魔法,而是明确的契约——你选择让谁进容器,谁才能享受自动装配。

















