一、模块化设计
一个完整的ThinkPHP应用基于 模块/控制器/操作 设计,并且,如果有需要的话,可以支持多入口文件和多级控制器
ThinkPHP3.2采用模块化的架构设计思想,对目录结构做了调整,可以支持多模块应用的创建,让应用的拓展更加方便。
一个典型的URL访问规则(默认URL规则是PATHINFO模式一例说明,当然和支持其他的模式)
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模块是一个特殊的模块,是应用的公共部分,访问所有的的模块之前都会首先加载公共模块下的配置文件和公共函数文件。但是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';
然后访问地址:http://servername/index.php
就会生成Admin模块的目录,并生产一个默认的控制器类Admin\Controller\IndexController.class.php.如果需要生产更多的的控制器类,可以定义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.class.php
Admin\Controller\UserController.class.php
Admin\Controller\MenuController.class.php
注意:默认生成的控制器类都是继承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
注意:默认生成的model类都是继承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
不同的入口文件还可以用于绑定不同的应用模式,参考应用模式部分。