必须使用 psr-15 兼容中间件实现请求前校验等功能,yii 3.0 已移除 servicelocator 和 yii::$app,所有依赖需显式注入;需 php ≥8.2,安装 yiisoft/middleware 包,语言中间件须注入 i18n 实例并按序注册。

要在 Yii 3.0 中实现请求前的身份校验、语言切换或日志记录,必须用 PSR-15 兼容的中间件类,不能沿用 Yii 2.x 的 AccessControl 行为或 beforeAction 写法——Yii 3.0 已彻底移除 ServiceLocator 隐式调用,所有中间件必须显式注册并参与请求生命周期链。
确认环境与依赖
执行 php -v 确保输出版本 ≥ 8.2,低于该版本会直接报错退出,且无法加载 PSR-15 接口定义。
运行 composer require yiisoft/middleware 安装官方中间件基础包;若需路由级调度,额外执行 composer require yiisoft/router。
【必须删除旧版 yii2-middleware 或自定义中间件类】:Yii 3.0 不识别任何继承自 yiiaseObject 或含 handle($request, $next) 但未实现 PsrHttpServerMiddlewareInterface 的类,否则启动时抛出 TypeError。
编写一个语言切换中间件
在 src/Middleware/LanguageMiddleware.php 创建文件:
声明命名空间并实现 PSR-15 接口,构造函数接收 yiii18nI18N 实例(非静态访问):
在 handle 方法中,从请求 URI 查询参数提取 language 值,验证是否为合法 locale(如 en-US、zh-CN),再调用 i18n->setLocale();最后返回 $next->handle($request) 继续链路。
注意:不要用 Yii::$app->i18n —— Yii 3.0 中没有全局 Yii::$app,所有依赖必须注入。
注册中间件到应用生命周期
打开 config/web.php,找到 'middleware' => [] 数组(若无则新建),按执行顺序从上到下追加中间件类名字符串:
第一步:'appMiddlewareLanguageMiddleware'
第二步:'yiisoft\middleware\TrustedHosts'(用于生产环境 Host 头校验)
第三步:'yiisoft\middleware\RequestBodyParser'(自动解析 JSON/form-data 请求体)
这三者顺序不可颠倒:语言切换必须早于请求体解析,否则部分 POST 请求可能因编码不匹配导致解析失败。
若要对某组路由单独启用中间件,不在此处注册,而改用路由器分组配置——在 config/routes.php 中使用 Group::create()->middleware(...)->add(...)。
调试中间件是否生效
启动内置服务器:php yii serve(确保已安装 yiisoft/server)。
访问 http://localhost:8080/?language=ja-JP,观察响应头中是否包含 X-App-Locale: ja-JP(需在 LanguageMiddleware 中手动添加该 Header)。
方法一:在中间件 handle 方法末尾插入 return $response->withHeader('X-App-Locale', $locale);;
方法二:用 curl 测试:curl -I "http://localhost:8080/?language=fr-FR",检查返回头是否含对应值。
如果返回 500 或空白响应,立即检查日志:tail -f runtime/logs/app.log,重点看 “Failed to resolve dependency” 或 “must implement MiddlewareInterface” 类错误。











