yii3模块化是包级解耦+运行时组装,非yii2式应用内划块;模块为可插拔composer包,依赖通过psr-11容器显式注入,无servicelocator和yii::$app。

Yii3 的模块化开发不是“加个模块就行”,而是从项目初始化那一刻起,就按组件拼装的逻辑来组织代码。它和 Yii2 的模块化思路有本质区别:Yii2 是“应用内划块”,Yii3 是“包级解耦+运行时组装”。上手关键不在于写多少代码,而在于理解怎么选、怎么配、怎么注入。
核心差异:模块不是“子应用”,而是可插拔的包
Yii2 的模块(Module)是挂载在应用实例下的逻辑单元,共享同一个 Application 对象和 ServiceLocator,本质上仍是单体结构里的分区;Yii3 没有传统意义上的 Module 类,取而代之的是独立 Composer 包(如 yiisoft/router、yiisoft/view),每个包只做一件事,彼此无隐式依赖。
- Yii2 中定义一个模块要继承
yii\base\Module,注册路由、配置组件、手动管理生命周期 - Yii3 中“添加路由功能”只需
composer require yiisoft/router,再在 DI 配置里绑定接口实现,框架自动发现并启用 - Yii2 模块间通信靠
Yii::$app->getModule('xxx'),容易形成强耦合;Yii3 用接口契约 + DI 注入,控制器直接声明依赖,不关心谁提供
上手第一步:从最小可运行包开始
别一上来就建“完整后台”,先跑通一个只处理 HTTP 请求的极简服务。Yii3 推荐从官方模板 yiisoft/app 或更轻量的 yiisoft/skeleton 启动:
- 执行
composer create-project yiisoft/app myapp,生成含核心容器、基础路由、响应处理的骨架 - 删掉不需要的包(比如不用数据库就
composer remove yiisoft/db),体积立刻缩小 30%+ - 查看
config/common.php和config/web.php,里面全是数组形式的 DI 绑定,没有魔法方法或全局静态调用
依赖注入不是“高级技巧”,而是唯一入口
Yii3 强制显式依赖——所有对象创建都走 DI 容器,不再有 Yii::$app->get('cache') 这类隐式获取。这意味着:
- 控制器构造函数必须声明所需服务,例如
public function __construct(private CacheInterface $cache) - 自定义组件需在配置中明确绑定接口到实现,如
CacheInterface::class => [FileCache::class, ['cachePath' => '@runtime/cache']] - 第三方库(如 monolog/logger)也能直接注入,只要它兼容 PSR-11,无需适配层
迁移 Yii2 项目时最常踩的坑
不是语法改了才叫难,而是旧习惯会悄悄导致运行时失败:
- 删掉所有
Yii::createObject()调用,改用构造注入或配置绑定 - 替换
Yii::$app->params为参数注入或配置值读取($config['params']['foo']) - 移除
bootstrap数组中的类名字符串,改用 DI 容器的onInit或事件监听器注册 - 检查是否还在用
__get()/__set()动态属性——PHP 8.2+ 下这会直接报错,Yii3 要求属性必须显式声明











