mycjk31 2017-06-07 10:25:43 7691次浏览 1条评论 6 2 0

▪ 环境

基于 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),你可以参阅 官方手册 进行了解。

其实高级模板中 frontendbackend 也可以理解为模块,但是他们可以单独部署(可以绑定独立的域名),所以他们又是高级模块(官方称之为应用主体),是所有其它自定义模块的根级别的父模块。

Yii2 的模块设计是可以无限嵌套的,但是默认安装完后,每个 应用主体 下面只有一个主模块,其 MVC 目录结构直接位于应用的根目录下。

利用 Yii2 的模块可以嵌套功能,我们可以在 frontend 这个 应用主体 下创建两个子模块index(前台) 和 admin(后台)
,这样前台和后台都是在同一个域名下(frontend.domain.com),这样就完美解决了文章开头所讲的问题了。

当然,因为后台以 子模块 的形式嵌入到 frontend 内了,那么系统自动创建 backend 就无用武之地。

▪ Yii2 模块代码

假定 frontend 应用主体绑定的域名为 frontend.domain.com,同时我们需要在 frontend 下面新增 indexadmin 两个子模块,操作如下:

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,打开的页面没有任何变化,这说明了现在应用主体还是访问之前默认的主模块,那如何才能访问到 indexadmin 子模块

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';

更多Yii2文章参见 https://my.oschina.net/lengdo/blog

觉得很赞
  • 评论于 2017-06-07 10:36 举报

    那么系统自动创建 backend 就无用武之地。
    那还不如直接使用basic版本,也用module

    2 条回复
    评论于 2017-06-07 10:43 回复

    那不行的,后期还有API独立,不使用子模块,到时直接改用backend

    评论于 2018-12-16 23:33 回复

    您好,这个API独立可以讲解一下吗?

您需要登录后才可以评论。登录 | 立即注册