🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
▪ 环境 基于 Yii2 高级模板 ▪ 前言 高级模板默认将前后台分离:frontend 前台应用 和 backend 后台应用,在使用时我们需要为这两个应用分别绑定域名,例如:frontend.domain.com,backend.domain.com 在我们常规的项目开发中,这种前后台独立分离的方式可能导致一些潜在的问题,最明显的问题比如: 1.在后台 backend 上传图片后(例如:/uploads/pic01.jpg),前台 frontend 无法直接访问通过 /uploads/pic01.jpg 这样的相对路径访问,因为前后台的域名是不一样的。 2.在后台的 Kindeditor 富文本框中添加了一些图片或附件(例如:/uploads/img01.jpg),那么前台 frontend 也无法直接访问通过 /uploads/img01.jpg 这样的相对路径访问,也是因为前后台的域名是不一样的。 3.... 当然你可能有很多解决方案,比如前台图片显示是增加后台的域名、服务器端设置 alias 访问 /uploads、使用类似阿里云OSS对象存储等等。 但是这些修改真的挺麻烦,我就开发一个小项目,我就想后台上传了就前台直接能访问,完全不想弄那么繁琐的配置,而 Yii2 的模块 Modules 功能就能很好的解决这个问题。 ▪ Yii2 模块介绍 关于 Yii2 的模块(Modules),你可以参阅 官方手册 进行了解。 其实高级模板中 frontend 和 backend 也可以理解为模块,但是他们可以单独部署(可以绑定独立的域名),所以他们又是高级模块(官方称之为应用主体),是所有其它自定义模块的根级别的父模块。 Yii2 的模块设计是可以无限嵌套的,但是默认安装完后,每个 应用主体 下面只有一个主模块,其 MVC 目录结构直接位于应用的根目录下。 利用 Yii2 的模块可以嵌套功能,我们可以在 frontend 这个 应用主体 下创建两个子模块:index(前台) 和 admin(后台) ,这样前台和后台都是在同一个域名下(frontend.domain.com),这样就完美解决了文章开头所讲的问题了。 当然,因为后台以 子模块 的形式嵌入到 frontend 内了,那么系统自动创建 backend 就无用武之地。 ▪ Yii2 模块代码 假定 frontend 应用主体绑定的域名为 frontend.domain.com,同时我们需要在 frontend 下面新增 index 和 admin 两个子模块,操作如下: 1. 新建子模块目录 \frontend\modules\index \frontend\modules\index\views \frontend\modules\index\models \frontend\modules\index\controllers \frontend\modules\admin \frontend\modules\admin\views \frontend\modules\admin\models \frontend\modules\admin\controllers 2. 新建子模块类 2.1 新建 index 子模块对象文件 \frontend\modules\index\Module.php,内容如下: <?php namespace frontend\modules\index; class Module extends \yii\base\Module { public function init() { parent::init(); } } 这个文件内的 类 主要供 应用主体 实例化模块对象。 2.2 新建 index 子模块的默认控制器文件 \frontend\modules\index\controllers\SiteController.php,内容如下: <?php namespace frontend\modules\index\controllers; use yii\web\Controller; class SiteController extends Controller { public function actionIndex() { echo 'You Access <b>'.$this->module->id.'</b> Sub Module'; exit(); } } 子模块 admin 也同样按照以上方式创建文件,注意需要把 index 改 admin 3. 配置子模块类 那 应用主体 如何知道它需要启动哪些模块呢?这个就需要我们将模块的信息写入到 应用主体 的配置文件里,编辑 /frontend/config/main.php,新增以下内容: 'modules' => [ 'index' => ['class'=>'frontend\modules\index\Module'], 'admin' => ['class'=>'frontend\modules\admin\Module'], ], 到此还没完,因为你会发现现在访问 frontend.domain.com,打开的页面没有任何变化,这说明了现在应用主体还是访问之前默认的主模块,那如何才能访问到 index 和 admin 子模块: http://frontend.domain.com/index.php?r=index/site/index http://frontend.domain.com/index.php?r=kernel/site/index 通过设置 URL 参数中的路由参数 r 即可,其格式为:r=[Module]/[Controller]/[Action] 4.调整子模块配置 4.1 设置 frontend 应用主体 的默认子模块 未设置前, Yii2 默认会直接访问 frontend 应用主体 的主模块,即 /frontend/controllers/SiteController;当然,我现在希望 Yii2 默认直接访问 index 子模块;编辑 /frontend/config/main.php,修改如下配置即可: # 设置默认的路由,格式:[Module]/[Controller]/[Action] # 以下配置可以在无路由参数的情况直接进入 index 子模块的 SiteController::actionIndex 'defaultRoute' => 'index/site/index'; # 设置默认的控制器命名空间 # 以下配置可以省略 URL 中路由参数的 [Module] 数据 'controllerNamespace' => 'frontend\modules\index\controllers' 4.2 设置子模块的默认布局 未设置前,frontend 应用主体 下的 子模块 默认都直接调用主模块的布局,即/frontend/views/layouts/main.php;明显,这策略不适合多个子模块,我们希望每个 子模块 默认调用其自身根目录下 views/layouts/main.php;编辑 子模块 根目录下的 Module.php,在 init() 函数内添加如下代码: # 该成员变量未设置值时,将调用父模块录的布局目 # 该成员变量被设置值后,将调用当前模块的布局目录 $this->layout = 'main';