# 模块化设计
[上一页](# "上一页")[下一页](# "下一页")
一个完整的ThinkPHP应用基于**模块/控制器/操作**设计,并且,如果有需要的话,可以支持多入口文件和多级控制器。
ThinkPHP3.2采用模块化的架构设计思想,对目录结构规范做了调整,可以支持多模块应用的创建,让应用的扩展更加方便。
一个典型的URL访问规则是(我们以默认的PATHINFO模式为例说明,当然也可以支持普通的URL模式):
~~~
http://serverName/index.php(或者其他应用入口文件)/模块/控制器/操作/[参数名/参数值...]
~~~
ThinkPHP3.2的应用可以支持切换到命令行访问,如果切换到命令行模式下面的访问规则是:
~~~
>php.exe index.php(或其它应用入口文件) 模块/控制器/操作/[参数名/参数值...]
~~~
解释下其中的几个概念:
| 名称 | 描述 |
|-----|-----|
| 应用 | 基于同一个入口文件访问的项目我们称之为一个应用。 |
| 模块 | 一个应用下面可以包含多个模块,每个模块在应用目录下面都是一个独立的子目录。 |
| 控制器 | 每个模块可以包含多个控制器,一个控制器通常体现为一个控制器类。 |
| 操作 | 每个控制器类可以包含多个操作方法,也可能是绑定的某个操作类,每个操作是URL访问的最小单元。 |
> 模块化设计的思想下面模块是最重要的部分,模块其实是一个包含配置文件、函数文件和MVC文件(目录)的集合。
### 模块设计
新版采用模块化的设计架构,下面是一个应用目录下面的模块目录结构,每个模块可以方便的卸载和部署,并且支持公共模块。
~~~
Application 默认应用目录(可以设置)
├─Common 公共模块(不能直接访问)
├─Home 前台模块
├─Admin 后台模块
├─... 其他更多模块
├─Runtime 默认运行时目录(可以设置)
~~~
> 注意:3.2版本在原来3.1.3的独立分组的基础上进行了改进,改进后的独立分组就是新版的模块,之前的模块则改称为控制器。 默认情况下,只要应用目录下面存在模块目录,该模块就可以访问,只有当你希望禁止某些模块或者仅允许模块访问的时候才需要进行模块列表的相关设置。
每个模块是相对独立的,其目录结构如下:
~~~
├─Module 模块目录
│ ├─Conf 配置文件目录
│ ├─Common 公共函数目录
│ ├─Controller 控制器目录
│ ├─Model 模型目录
│ ├─Logic 逻辑目录(可选)
│ ├─Service Service目录(可选)
│ ... 更多分层目录可选
│ └─View 视图目录
~~~
> 由于采用多层的MVC机制,除了Conf和Common目录外,每个模块下面的目录结构可以根据需要灵活设置和添加,所以并不拘泥于上面展现的目录
### 公共模块
Common模块是一个特殊的模块,是应用的公共模块,访问所有的模块之前都会首先加载公共模块下面的配置文件(`Conf/config.php`)和公共函数文件(`Common/function.php`)。但Common模块本身不能通过URL直接访问,公共模块的其他文件则可以被其他模块继承或者调用。
公共模块的位置可以通过**COMMON_PATH**常量改变,我们可以在入口文件中重新定义**COMMON_PATH**如下:
~~~
define('COMMON_PATH','./Common/');
define('APP_PATH','./Application/');
require './ThinkPHP/ThinkPHP.php';
~~~
其应用目录结构变成:
~~~
www WEB部署目录(或者子目录)
├─index.php 入口文件
├─README.md README文件
├─Common 应用公共模块目录
├─Application 应用模块目录
├─Public 应用资源文件目录
└─ThinkPHP 框架目录
~~~
> 定义之后,Application目录下面就不再需要Common目录了。
### 自动生成模块目录
从**3.2.2版本**开始,可以支持自动生成默认模块之外的模块目录以及批量生成控制器和模型类。
例如,如果我们需要生成一个Admin模块用于后台应用,在应用入口文件中定义如下:
~~~
// 绑定Admin模块到当前入口文件
define('BIND_MODULE','Admin');
define('APP_PATH','./Application/');
require './ThinkPHP/ThinkPHP.php';
~~~
然后访问URL地址
~~~
http://serverName/index.php
~~~
就会生成Admin模块的目录,并生成一个默认的控制器类`Admin\Controller\IndexController`。如果需要生成更多的控制器类,可以定义`BUILD_CONTROLLER_LIST`常量,例如:
~~~
// 绑定Admin模块到当前入口文件
define('BIND_MODULE','Admin');
define('BUILD_CONTROLLER_LIST','Index,User,Menu');
define('APP_PATH','./Application/');
require './ThinkPHP/ThinkPHP.php';
~~~
访问后会自动生成三个指定的控制器类:
~~~
Admin\Controller\IndexController
Admin\Controller\UserController
Admin\Controller\MenuController
~~~
> 注意:默认生成的控制器类都是继承`Think\Controller`,如果需要继承其他的公共类需要另外调整。 如果在应用的公共配置文件中设置关闭了 `APP_USE_NAMESPACE`的话,生成的控制器类则不会采用命名空间定义。
还可以自己手动调用`Think\Build`类的方法来生成控制器类,例如:
~~~
// 生成Admin模块的Role控制器类
// 默认类库为Admin\Controller\RoleController
// 如果已经存在则不会重新生成
\Think\Build::buildController('Admin','Role');
~~~
同样,也可以定义`BUILD_MODEL_LIST`支持生成多个模型类:
~~~
// 绑定Admin模块到当前入口文件
define('BIND_MODULE','Admin');
define('BUILD_CONTROLLER_LIST','Index,User,Menu');
define('BUILD_MODEL_LIST','User,Menu');
define('APP_PATH','./Application/');
require './ThinkPHP/ThinkPHP.php';
~~~
访问会自动生成模型类:
~~~
Admin\Model\UserModel
Admin\Model\MenuModel
~~~
> 注意:默认生成的模型类都是继承`Think\Model`,如果需要继承公共的模型类需要另外调整。 如果在应用的公共配置文件中设置关闭了 `APP_USE_NAMESPACE`的话,生成的模型类则不会采用命名空间定义。
也可以自己手动调用Think\Build类的方法来生成模型类,例如:
~~~
// 生成Admin模块的Role模型类
// 默认类库为Admin\Model\RoleModel
// 如果已经存在则不会重新生成
\Think\Build::buildModel('Admin','Role');
~~~
### 禁止访问模块
3.2对模块的访问是自动判断的,所以通常情况下无需配置模块列表即可访问,但可以配置禁止访问的模块列表(用于被其他模块调用或者不开放访问),默认配置中是禁止访问`Common`模块和`Runtime`模块(Runtime目录是默认的运行时目录),我们可以增加其他的禁止访问模块列表:
~~~
// 设置禁止访问的模块列表
'MODULE_DENY_LIST' => array('Common','Runtime','Api'),
~~~
设置后,Api模块不能通过URL直接访问,事实上,可能我们只是在该模块下面放置一些公共的接口文件,因此都是内部调用即可。
### 设置访问列表
如果你的应用下面模块比较少,还可以设置允许访问列表和默认模块,这样可以简化默认模块的URL访问。
~~~
'MODULE_ALLOW_LIST' => array('Home','Admin','User'),
'DEFAULT_MODULE' => 'Home',
~~~
设置之后,除了Home、Admin和User模块之外的模块都不能被直接访问,并且Home模块是默认访问模块(可以不出现在URL地址)。
### 单模块设计
如果你的应用够简单,那么也许仅仅用一个模块就可以完成,那么可以直接设置:
~~~
// 关闭多模块访问
'MULTI_MODULE' => false,
'DEFAULT_MODULE' => 'Home',
~~~
一旦关闭多模块访问后,就只能访问默认模块(这里设置的是Home)。
> 单模块设计后公共模块依然有效
### 多入口设计
可以给相同的应用及模块设置多个入口,不同的入口文件可以设置不同的应用模式或者绑定模块。
例如,我们在`index.php`文件的同级目录新增一个`home.php`入口文件,并绑定Home模块:
**3.2.0版本写法:**
~~~
// 绑定Home模块到当前入口文件
$_GET['m'] = 'Home';
define('APP_PATH','./Application/');
require './ThinkPHP/ThinkPHP.php';
~~~
**3.2.1以上版本写法:**
~~~
// 绑定Home模块到当前入口文件
define('BIND_MODULE','Home');
define('APP_PATH','./Application/');
require './ThinkPHP/ThinkPHP.php';
~~~
> 如果你更改了系统默认的变量设置,则需要做对应的模块绑定的变量调整。
绑定模块后,原来的访问地址
~~~
http://serverName/index.php/Home/Index/index
~~~
就变成
~~~
http://serverName/home.php/Index/index
~~~
同样的方式,我们也可以在入口文件中绑定控制器,例如:
**3.2.0版本写法:**
~~~
$_GET['m'] = 'Home'; // 绑定Home模块到当前入口文件
$_GET['c'] = 'Index'; // 绑定Index控制器到当前入口文件
define('APP_PATH','./Application/');
require './ThinkPHP/ThinkPHP.php';
~~~
**3.2.1以上版本写法:**
~~~
define('BIND_MODULE', 'Home'); // 绑定Home模块到当前入口文件
define('BIND_CONTROLLER','Index'); // 绑定Index控制器到当前入口文件
define('APP_PATH','./Application/');
require './ThinkPHP/ThinkPHP.php';
~~~
绑定模块和控制器后,原来的访问地址:
~~~
http://serverName/index.php/Home/Index/index
~~~
就变成:
~~~
http://serverName/home.php/index
~~~
> 不同的入口文件还可以用于绑定不同的应用模式,参考[应用模式](#)部分。
[上一页](# "上一页")[下一页](# "下一页")
- 序言
- 基础
- 获取ThinkPHP
- 环境要求
- 目录结构
- 入口文件
- 自动生成
- 模块
- 控制器
- 开发规范
- 配置
- 配置格式
- 配置加载
- 读取配置
- 动态配置
- 扩展配置
- 批量配置
- 架构
- 模块化设计
- URL模式
- 多层MVC
- CBD模式
- 命名空间
- 自动加载
- 应用模式
- 项目编译
- 系统流程
- 路由
- 路由定义
- 规则路由
- 正则路由
- 静态路由
- 闭包支持
- 实例说明
- 控制器
- 控制器定义
- 前置和后置操作
- Action参数绑定
- 伪静态
- URL大小写
- URL生成
- AJAX返回
- 跳转和重定向
- 输入变量
- 请求类型
- 空操作
- 空控制器
- 操作绑定到类
- 模型
- 模型定义
- 模型实例化
- 字段定义
- 连接数据库
- 切换数据库
- 分布式数据库支持
- 连贯操作
- WHERE
- TABLE
- ALIAS
- DATA
- FIELD
- ORDER
- LIMIT
- PAGE
- GROUP
- HAVING
- JOIN
- UNION
- DISTINCT
- LOCK
- CACHE
- COMMENT
- RELATION
- 命名范围
- CURD操作
- 数据创建
- 数据写入
- 数据读取
- 数据更新
- 数据删除
- ActiveRecord
- 字段映射
- 查询语言
- 查询方式
- 表达式查询
- 快捷查询
- 区间查询
- 组合查询
- 统计查询
- SQL查询
- 动态查询
- 子查询
- 自动验证
- 自动完成
- 参数绑定
- 虚拟模型
- 模型分层
- 视图模型
- 关联模型
- 高级模型
- Mongo模型
- 视图
- 模板定义
- 模板主题
- 模板赋值
- 模板渲染
- 获取模板地址
- 获取内容
- 模板引擎
- 模板
- 变量输出
- 系统变量
- 使用函数
- 默认值输出
- 使用运算符
- 标签库
- 模板继承
- 修改定界符
- 三元运算
- 包含文件
- 内置标签
- Volist标签
- Foreach标签
- For标签
- Switch标签
- 比较标签
- 范围判断标签
- IF标签
- Present标签
- Empty标签
- Defined标签
- Assign标签
- Define标签
- 标签嵌套
- import标签
- 使用PHP代码
- 原样输出
- 模板注释
- 模板布局
- 模板替换
- 调试
- 调试模式
- 异常处理
- 日志记录
- 页面Trace
- Trace方法
- 变量调试
- 性能调试
- 错误调试
- 模型调试
- 缓存
- 数据缓存
- 快速缓存
- 查询缓存
- SQL解析缓存
- 静态缓存
- 安全
- 输入过滤
- 表单合法性检测
- 表单令牌
- 防止SQL注入
- 目录安全文件
- 保护模板文件
- 上传安全
- 防止XSS攻击
- 其他安全建议
- 扩展
- 类库扩展
- 驱动扩展
- 缓存驱动
- 数据库驱动
- 日志驱动
- Session驱动
- 存储驱动
- 模板引擎驱动
- 标签库驱动
- 行为扩展
- 标签扩展
- Widget扩展
- 应用模式
- 部署
- PATH_INFO支持
- URL重写
- 模块部署
- 域名部署
- 入口绑定
- 替换入口
- 专题
- SESSION支持
- Cookie支持
- 多语言支持
- 数据分页
- 文件上传
- 验证码
- 图像处理
- RESTFul
- RPC
- SAE
- IP获取和定位
- 附录
- 常量参考
- 配置参考
- 升级指导
- 更新日志
- 鸣谢
- 关于