thinkphp 模块化设计
一个完整的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 模块化设计的更多相关文章
- thinkphp学习笔记5—模块化设计
原文:thinkphp学习笔记5-模块化设计 1.模块结构 完整的ThinkPHP用用围绕模块/控制器/操作设计,并支持多个入口文件盒多级控制.ThinkPHP默认PATHINFO模式,如下: htt ...
- iOS程序模块化设计
一.模块化设计的概述: 模块化设计(Block-based design):对一定范围内的不同功能或相同功能的不同性能.不同规格的产品进行功能分析的基础上,划分并设计出一系列功能模块,通过模块的选择和 ...
- PHP--进行模块化设计
PHP--进行模块化设计 [来源] 达内 [编辑] 达内 [时间]2012-10-30 导航模块可以简单列为一个关于三级页面链接的HTML文件.通常你可以通过用另一种颜色来标明对当前区域的链 ...
- 深入浅出百度地图API开发系列(3):模块化设计
在前面两张简单介绍了百度地图API的基础知识和使用之后,我们来分析一下百度地图API的基本架构,了解一下基本架构可以帮助我们更清晰的了解API的功能和调用过程,也就可以帮助我们在实际开发中可以更方便的 ...
- AngularJs学习笔记7——四大特性之模块化设计
模块化设计 1.引用自定义模块并调用 自定义模块中,如果有一些服务.封装好笑模块,在另外一个模块中(声明的时候,在依赖列表中加入要引入的模块) var app02 = angular.module(' ...
- C51的模块化设计方法
一个大的单片机程序往往包含很多模块,我是这样组织的: 1.每一个C源文件都要建立一个与之名字一样的H文件(头文件),里面仅仅包括该C文件的函数的声明,其他的什么也不会有,比如变量的定义啊等等不应该有. ...
- App 组件化/模块化之路——使用SDK的思路进行模块化设计接口
在不久之前分享一篇<App 组件化/模块化之路——如何封装网络请求框架>文章介绍了我在项目中封装网络请求框架的思路.开发一个 App 会涉及到很多网络请求 API ,例如登录注册接口.用户 ...
- 基于layui的框架模版,采用模块化设计,接口分离,组件化思想
代码地址如下:http://www.demodashi.com/demo/13362.html 1. 准备工作 编辑器vscode,需要安装liveServer插件在前端开启静态服务器 或者使用hbu ...
- Swift之xib模块化设计
一.解决问题 Xib/Storybarod可以方便.可视化的设置约束,在开发中也越来越重要.由于Xib不能组件化,使得封装.重用都变得不可行.本文将介绍一种解决方案,来实现Xib组件化. 二.模型块原 ...
随机推荐
- Reqests----Get请求之参数化
一.环境安装 >>pip install requests 注意:pip很容易就会版本升级,如果用python3的,请使用pip3 install requests 1.初始化版本 2.把 ...
- android中的属性资源
属性资源可以很好的控制自定义View组件的外观行为. 属性资源放置在/res/values目录下,属性资源文件的根目录元素是<resources.../>,该元素包含如下两个子元素: at ...
- C#跨线程访问(一) ---- SynchronizationContext
一.SynchronizationContext顾名思义是同步上下文的意思.利用此对象可以实现线程间数据的同步.异步访问. 二.例子 class Program { static Thread _wo ...
- webpack4.0基础
安装 yarn add webpack webpack-cli -D npx webpack index.js 图片 file-loader module: { rules: [ { test: /\ ...
- NX二次开发-UFUN获取当前所在的模块UF_ask_application_module
NX9+VS2012 #include <uf.h> #include <NXOpen/UI.hxx> #include <NXOpen/MenuBar_MenuBarM ...
- (转) mysql的分区技术 .
转:http://blog.csdn.net/feihong247/article/details/8100960 一.概述 当 MySQL的总记录数超过了100万后,会出现性能的大幅度下降吗?答案是 ...
- Java-Class-C:org.springframework.http.MediaType
ylbtech-Java-Class-C:org.springframework.http.MediaType 1.返回顶部 1.1. /* * Copyright 2002-2018 the ori ...
- StringUtils里的isEmpty方法和isBlank方法的区别
原文地址:https://blog.csdn.net/a1102325298/article/details/80410740 isEmpty public static boolean isEmpt ...
- 两个问题: 1、头文件重复包含 2、头文件加了ifndef条件预处理指令为什么还会定义
第一个问题:编译时重定义 文件1.h void fun1(); struct A { int a char b; }; 文件2.h #include"1.h" struct B ...
- scanf 与getchar区别
#include<stdio.h> void main() { int c; c=getchar(); //scanf("%c",&c); if(c!=' ...