首页 > 代码库 > ThinkPHP 3.2.3(三)架构之模块化设计

ThinkPHP 3.2.3(三)架构之模块化设计

一、概念
应用:基于同一个入口文件访问的项目称之为一个应用。
模块:一个应用下面可以包含多个模块,每个模块在应用目录下面都是一个独立的子目录,是一个包含配置文件、函数文件和MVC文件(目录)的集合。
控制器:每个模块可以包含多个控制器,一个控制器通常体现为一个控制器类。
操作:每个控制器类可以包含多个操作方法,也可能是绑定的某个操作类,每个操作是URL访问的最小单元。
 
二、典型的URL访问规则
http://serverName/index.php(或者其他应用入口文件)/模块/控制器/操作/[参数名/参数值...]
 
三、模块设计
一个应用目录下面的模块目录结构如下,每个模块可以方便卸载和部署,并且支持公共模块。只要应用目录下面存在模块目录,该模块就可以访问。
Application      默认应用目录(可以设置)
├─Common         公共模块(不能直接访问)
├─Home           前台模块
├─Admin          后台模块
├─...            其他更多模块
├─Runtime        默认运行时目录(可以设置)
 
每个模块是相对独立的,其目录结构如下:
├─Module         模块目录
│  ├─Conf        配置文件目录
│  ├─Common      公共函数目录
│  ├─Controller  控制器目录
│  ├─Model       模型目录
│  ├─Logic       逻辑目录(可选)
│  ├─Service     Service目录(可选)
│  ... 更多分层目录可选
│  └─View        视图目录
 
四、公共模块Common
Common模块本身不能通过URL直接访问,公共模块的其他文件则可以被其他模块继承或者调用。
技术分享
手册说,访问所有的模块之前都会首先加载公共模块下面的配置文件(Conf/config.php)和公共函数文件(Common/function.php),但并没有找到function.php文件。
 
手册说, 公共模块的位置可以通过在入口文件中定义COMMON_PATH常量来改变。
define(‘COMMON_PATH‘,‘./Common/‘);
在入口文件中定义该常量后,其应用目录结构变成:
www  WEB部署目录(或者子目录)
├─index.php       入口文件
├─README.md       README文件
├─Common          应用公共模块目录     // 定义之后,Application目录下面不再需要Common目录了
├─Application     应用模块目录
├─Public          应用资源文件目录
└─ThinkPHP        框架目录
但实际操作中,目录结构并没有变化。
 
五、自动生成模块目录
1、生成一个模块
例如,如果需要生成一个Admin模块用于后台应用,在应用入口文件中定义如下:
// 绑定Admin模块到当前入口文件
define(‘BIND_MODULE‘,‘Admin‘);
define(‘APP_PATH‘,‘./Application/‘);
require ‘./ThinkPHP/ThinkPHP.php‘;
然后访问入口文件http://localhost/ThinkPHP-3.2.3/index.php, 会生成Admin模块的目录,并生成一个默认的控制器类Admin\Controller\IndexController
技术分享
这个时候访问http://localhost/ThinkPHP-3.2.3/index.php/home/index/index,报错:
技术分享
需要删除或注释掉那段常量定义的语句define(‘BIND_MODULE‘,‘Admin‘); 才能正常访问Home模块。
 
同时发现一个问题:
自动生成模块目录时,define(‘BIND_MODULE‘,‘Admin‘);语句要放到require ‘./ThinkPHP/ThinkPHP.php‘;上面,否则不会生成模块。
// 绑定Admin模块到当前入口文件
define(‘BIND_MODULE‘,‘Admin‘);
define(‘APP_PATH‘,‘./Application/‘);
require ‘./ThinkPHP/ThinkPHP.php‘;
生成后,访问http://localhost/ThinkPHP-3.2.3/index.php没有问题,是Admin模块默认的“欢迎使用ThinkPHP页面”。
但是访问http://localhost/ThinkPHP-3.2.3/index.php/Admin/Index/index会报错
技术分享
需要将define(‘BIND_MODULE‘,‘Admin‘);语句要放到require ‘./ThinkPHP/ThinkPHP.php‘;下面,才能正常访问。
 
2、生成多个控制器类和模型类
如果需要生成更多的控制器类,可以定义BUILD_CONTROLLER_LIST常量,例如:
// 绑定Admin模块到当前入口文件
define(‘BIND_MODULE‘,‘Admin‘);
define(‘BUILD_CONTROLLER_LIST‘,‘Index,User,Menu‘);     // 模型类为BUILD_MODEL_LIST
define(‘APP_PATH‘,‘./Application/‘);
require ‘./ThinkPHP/ThinkPHP.php‘;
问题1:访问后并没有生成如手册所说的控制类
Admin\Controller\IndexController
Admin\Controller\UserController
Admin\Controller\MenuController
问题2:重新搭ThinkPHP框架后,第一次访问入口文件后生成了多个控制类,但是再想生成别的控制类,依然失败。
百度了这个问题,有人也遇到与我类似的问题,解决方法是可以将已经生成的模块删除,然后重新访问入口文件,就可以生成该模块和对应的多个控制类了。
 
3、手动生成控制器类和模型类
手动调用Think\Build类的方法来生成控制器类和模型类,例如:
// 生成Admin模块的Role控制器类                          or 模型类
// 默认类库为Admin\Controller\RoleController           or Admin\Model\RoleModel
// 如果已经存在则不会重新生成
\Think\Build::buildController(‘Admin‘,‘Role‘);        or \Think\Build::buildModel(‘Admin‘,‘Role‘);
报错:Fatal error: Class ‘Think\Build‘ not found in D:\xampp\htdocs\ThinkPHP-3.2.3\index.php on line 25
调试时发现:调用Think\Build类中方法的语句应放在引用ThinkPHP入口文件语句(require ‘./ThinkPHP/ThinkPHP.php‘; )的下面。
 
调用Think\Build类的方法还可以写成:
require ‘./ThinkPHP/ThinkPHP.php‘;
 
include ‘./ThinkPHP/Library/Think/Build.class.php‘;
$build = new \Think\Build();
$build->buildController(‘Admin‘,‘Role‘);
 
六、禁止访问模块
默认配置中是禁止访问Common模块和Runtime模块(Runtime目录是默认的运行时目录)。
手册说,可以增加其他的禁止访问模块列表:
// 设置禁止访问的模块列表
‘MODULE_DENY_LIST‘      =>  array(‘Common‘,‘Runtime‘,‘Api‘),
设置后,Api模块不能通过URL直接访问。
一开始不知道这个配置是需要在入口文件里自定义还是在Application/Common/Conf下的config.php文件里定义,后来在/ThinkPHP/Conf/convention.php文件里找到了这个配置。
技术分享
 
把自己生成的Admin模块添加进去,
技术分享
访问http://localhost/ThinkPHP-3.2.3/index.php/Admin/Index/index,无法加载Admin模块,说明禁止访问模块成功。
 
七、设置访问列表
如果应用下面模块比较少,还可以设置允许访问列表和默认模块,这样可以简化默认模块的URL访问。
‘MODULE_ALLOW_LIST‘   =>    array(‘Home‘,‘Admin‘,‘User‘),
‘DEFAULT_MODULE‘      =>    ‘Home‘,
设置之后,除了Home、Admin和User模块之外的模块都不能被直接访问,并且Home模块是默认访问模块(可以不出现在URL地址)。
 
以上为手册原话,然而这项配置好像没什么用?而且,所谓的直接访问指的是什么?并且在/ThinkPHP/Conf/convention.php文件里并没有找到MODULE_ALLOW_LIST这项配置。
生成模块后,直接访问http://localhost/ThinkPHP-3.2.3/home(或admin或user)均可访问。
 
八、单模块设计
将/ThinkPHP/Conf/convention.php文件里的MULTI_MODULE由true改为false,如果为false 则必须设置 DEFAULT_MODULE。
// 关闭多模块访问
‘MULTI_MODULE‘          =>  false,
‘DEFAULT_MODULE‘        =>  ‘Home‘,
一旦关闭多模块访问后,就只能访问默认模块(这里设置的是Home)。
问题:url只有为http://localhost/ThinkPHP-3.2.3/index.php时才能访问,其余形式如http://localhost/ThinkPHP-3.2.3/index.php/home或http://localhost/ThinkPHP-3.2.3/index.php/home/index/index等方式均不能访问了。
 
九、多入口设计
可以给相同的应用及模块设置多个入口,不同的入口文件可以设置不同的应用模式或者绑定模块。
例如,在index.php文件的同级目录新增一个admin.php入口文件,并绑定Admin模块:
// 绑定Admin模块到当前入口文件
define(‘BIND_MODULE‘,‘Admin‘);
define(‘APP_PATH‘,‘./Application/‘);
require ‘./ThinkPHP/ThinkPHP.php‘;
原来的访问地址http://localhost/ThinkPHP-3.2.3/index.php/Admin/Index/index可以改为http://localhost/ThinkPHP-3.2.3/admin.php/Index/index。
 
同理,将index.php绑定Home模块
原来的访问地址http://localhost/ThinkPHP-3.2.3/index.php/Home/Index/index可以改为http://localhost/ThinkPHP-3.2.3/home.php/Index/index。这时出现Internal Server Error:
技术分享
这是因为没有将index.php文件重命名,重命名为home.php后可以正常访问。

ThinkPHP 3.2.3(三)架构之模块化设计