要在 yii 3.0 项目中真正落地 psr 标准,必须显式配置 psr-4 命名空间映射、psr-11 容器绑定规则、psr-7 消息工厂实例和 psr-15 中间件注册顺序,否则依赖注入失败、路由不生效、请求对象无法构造等问题会立刻暴露。

要在 Yii 3.0 项目中真正落地 PSR 标准,不能只靠 composer autoload 自动加载——必须显式配置 PSR-4 命名空间映射、PSR-11 容器绑定规则、PSR-7 消息工厂实例和 PSR-15 中间件注册顺序,否则依赖注入失败、路由不生效、请求对象无法构造等问题会立刻暴露。
配置 PSR-4 自动加载规则
打开项目根目录下的 composer.json 文件,在 autoload 字段中声明应用代码的命名空间路径映射。
添加如下内容(注意缩进与逗号):
"autoload": {<br> "psr-4": {<br> "App\": "src/",<br> "Tests\": "tests/"<br> }<br>}
这一步必须在运行 composer dump-autoload 前完成,否则新增类文件不会被识别。
执行 composer dump-autoload -o 生成优化后的自动加载映射表,【不加 -o 参数会导致开发时类加载变慢,且部分测试环境无法通过】。
注册 PSR-11 兼容容器
Yii 3.0 不再提供全局 Yii::$app,所有服务必须通过 PSR-11 容器获取。容器实例由 yiisoft/di 提供,默认已在入口文件中初始化。
在 config/common.php 中返回一个 Configurator 实例,用 set() 方法绑定接口与实现:
$container->set(LoggerInterface::class, FileLogger::class);
$container->set(CacheInterface::class, RedisCache::class);
注意:接口类必须使用完整命名空间,且 【不能用字符串代替接口常量,如 'PsrLogLoggerInterface' 会报错】。
若需条件绑定(例如开发环境用 FileLogger,生产环境用 SyslogLogger),改用 setIf() 并传入回调判断逻辑。
启用 PSR-7 HTTP 消息支持
Yii 3.0 默认使用 PSR-7 请求/响应对象,但需手动注册 PSR-17 工厂才能构造新实例。
方法一:在 config/web.php 的 dependencies 配置块中注册工厂:
'psr/http-factory' => PsrHttpMessageResponseFactoryInterface::class,
'psr/http-message' => PsrHttpMessageServerRequestInterface::class,
方法二:直接在容器中绑定具体实现:
$container->set(ResponseFactoryInterface::class, DiactorosResponseFactory::class);
$container->set(ServerRequestFactoryInterface::class, DiactorosServerRequestFactory::class);
推荐使用方法二,因为 Diactoros* 是社区最稳定兼容的 PSR-7 实现,避免因工厂未注册导致 new Response() 报错。
注册 PSR-15 中间件栈
第一步:确认已安装中间件扩展:composer require yiisoft/middleware-dispatcher。
第二步:在 config/web.php 中找到 middleware 键,按执行顺序从上到下排列:
① YiisoftMiddlewareTrustedHosts::class —— 必须放在最前,防止 Host 头伪造攻击;
② YiisoftMiddlewareBodyParser::class —— 解析 JSON/FORM 数据,控制器才能读取 $request->getParsedBody();
③ YiisoftYiiWebRouter::class —— 路由分发,必须在 BodyParser 之后、Controller 之前;
④ AppMiddlewareAuthentication::class —— 自定义鉴权中间件,放在 Router 后确保能拿到匹配的路由参数;
⑤ YiisoftYiiWebErrorHandler::class —— 错误处理,必须放在最后兜底。
中间件顺序不可颠倒,否则 $request 可能未解析、路由未匹配或错误未捕获。











