核心是nginx/apache需为frontend和backend分别配置独立server块,指向各自web目录,而非依赖yii2路由;二者为物理隔离的独立应用,共享common但运行时零共享。

怎么让 frontend 和 backend 绑定不同域名
核心就一条:Web 服务器(Nginx/Apache)必须把两个子目录分别映射为独立站点,而不是靠 Yii2 自己“路由”区分。Yii2 的高级模板默认是单入口、双应用结构,但 frontend/web 和 backend/web 是物理隔离的两个 Web 根目录,天然支持分域。
实操建议:
- Nginx 中为
frontend单独配一个server块,root指向/path/to/your/project/frontend/web,server_name设为www.example.com - 再配一个
server块给backend,root指向/path/to/your/project/backend/web,server_name设为admin.example.com - 两个配置里都保留标准的 PHP-FPM fastcgi_pass 和 index 配置,别漏掉
try_files $uri $uri/ /index.php?$args - 绝对不要把 backend 放在 frontend 下做子路径(比如
/admin),否则会触发跨应用 session 冲突和 asset 发布错乱
为什么不能只改 urlManager 或 bootstrap
因为 urlManager 管的是请求进来后的路由解析,它不控制 HTTP Host 头、不决定哪个 index.php 先被执行。高级模板中 frontend/web/index.php 和 backend/web/index.php 是两个完全独立的入口文件,各自加载各自的 Application 实例和配置。
常见错误现象:
- 只改了
common/config/main.php里的urlManager规则,结果访问admin.example.com时 404 —— 因为 Nginx 根本没把请求转给backend/web/index.php - 在
frontend/config/main.php里加了'bootstrap' => ['backend'],直接报Class 'backend' not found—— 这不是模块加载方式,backend不是 frontend 的模块,是另一个应用 - 用
Yii::setAlias('@backend', dirname(__DIR__) . '/backend');在 frontend 里试图“引用”backend,会导致 autoloader 混乱,vendor 类重复注册
index.php 和 config/web.php 要不要动
绝大多数情况:不动。高级模板的 frontend/web/index.php 和 backend/web/index.php 已经各自指向正确的应用入口,config/web.php 也已按应用拆分。你唯一需要确认的是:
-
frontend/web/index.php第 13 行是否为(new yii\web\Application($config))->run();—— 是,说明它启动的是 frontend 应用 -
backend/web/index.php同理,应指向yii\console\Application?不对,这里必须是yii\web\Application,且 $config 来自backend/config目录 - 如果用了自定义环境(如
local/prod),确保YII_ENV在两个入口文件里都正确设置,否则common/config/main-local.php可能被误加载 - 别在
frontend/config/main.php里写'name' => 'Admin Panel'这种混淆项,名字只影响当前应用显示,不影响路由或域名
HTTPS、cookie 域名和 asset 发布容易踩的坑
分域后最隐蔽的问题不在路由,而在状态和资源加载:
- Session cookie 默认绑定到当前域名,
frontend登录后backend看不到用户 —— 解决方法是在backend/config/main.php和frontend/config/main.php的'user'组件里统一设'identityCookie' => ['domain' => '.example.com'](注意开头的点) -
assetManager的baseUrl如果写死为/assets,在admin.example.com下会尝试从https://admin.example.com/assets/xxx.js加载,但实际文件在backend/web/assets/—— 正确做法是保持默认,让 Yii 自动根据当前应用生成路径 - 如果启用了
AssetBundle的publishOptions['forceCopy'] = true,注意磁盘空间,两个应用各自 publish 一份相同资源,体积翻倍 - 本地开发用
localhost测试多域名?Chrome 会拒绝.localhost的 cookie,改用frontend.test+backend.test并在 hosts 里配好,更可靠
域名一拆开,frontend 和 backend 就彻底是两个独立服务了。它们共用 common 和 console,但运行时零共享 —— 这既是设计优势,也是调试时最容易忽略的前提。











