MVC和三层结构
MVC可以说是一种开发模式,三层结构是一种开发习惯,严格来讲,他们两者是完全不同的概念,但是在实际开发当中又有各种联系;
MVC是一种将视图、控制器、数据三种分开的一种开发模式。
M - Model 模型 工作:编写module类,负责数据的操作
V - View 视图(模板) 工作:编写html文件,负责前台页面展示
C - Controller 控制器 工作:编写类文件,IndexController.class.php
ThinkPHP 3.2.3介绍
ThinkPHP是一个快速、简单的基于MVC和面向对象的轻量级PHP开发框架,遵循Apache2开源协议发布,从诞生以来一直秉承简洁实用的设计原则,在保持出色的性能和至简的代码的同时,尤其注重开发体验和易用性,并且拥有众多的原创功能和特性,为WEB应用开发提供了强有力的支持。
下载:http://www.thinkphp.cn/donate/download/id/610.html
官方文档:https://www.kancloud.cn/manual/thinkphp/1678
ThinkPHP 3.2.3核心文件和模块
几个概念:
名称 | 描述 |
---|---|
应用 | 基于同一个入口文件访问的项目我们称之为一个应用。 |
模块 | 一个应用下面可以包含多个模块,每个模块在应用目录下面都是一个独立的子目录。 |
控制器 | 每个模块可以包含多个控制器,一个控制器通常体现为一个控制器类。 |
操作 | 每个控制器类可以包含多个操作方法,也可能是绑定的某个操作类,每个操作是URL访问的最小单元。 |
模块化设计的思想下面模块是最重要的部分,模块其实是一个包含配置文件、函数文件和MVC文件(目录)的集合。
下载框架后,解压缩到web目录下面,可以看到初始的目录结构如下:
www WEB部署目录(或者子目录)
├─index.php 入口文件
├─README.md README文件
├─Application 应用目录
├─Public 资源文件目录
└─ThinkPHP 框架目录
开发人员可以在这个基础之上灵活调整。其中,Application
和Public
目录下面都是空的。
README.md文件仅用于说明,实际部署的时候可以删除。 上面的目录结构和名称是可以改变的,这取决于你的入口文件和配置参数。 Application目录默认是空的,但是第一次访问入口文件会自动生成,参考后面的入口文件部分。
其中框架目录ThinkPHP的结构如下:
├─ThinkPHP 框架系统目录(可以部署在非web目录下面)
│ ├─Common 核心公共函数目录
│ ├─Conf 核心配置目录
│ ├─Lang 核心语言包目录
│ ├─Library 框架类库目录
│ │ ├─Think 核心Think类库包目录
│ │ ├─Behavior 行为类库目录
│ │ ├─Org Org类库包目录
│ │ ├─Vendor 第三方类库目录
│ │ ├─ ... 更多类库目录
│ ├─Mode 框架应用模式目录
│ ├─Tpl 系统模板目录
│ ├─LICENSE.txt 框架授权协议文件
│ ├─logo.png 框架LOGO文件
│ ├─README.txt 框架README文件
│ └─ThinkPHP.php 框架入口文件
上述应用的目录结构只是默认设置,事实上,在实际部署应用的时候,我们建议除了应用入口文件和
Public
资源目录外,其他文件都放到非WEB目录下面,具有更好的安全性。
Model.class.php
位于:ThinkPHP\Library\Model.class.php
包含很多对数据操作的连贯操作,如:where、order、setInc、setDec...
Driver.class.php
位于:ThinkPHP\Library\Think\Db\Driver.class.php
数据条件分析,各种操作数据库
比如Model.class.php中存在limit,则在Driver.class.php中存在一个parseLimit对上面的limit进行分析操作。
模块设计
新版采用模块化的设计架构,下面是一个应用目录下面的模块目录结构,每个模块可以方便的卸载和部署,并且支持公共模块。
Application 默认应用目录(可以设置)
├─Common 公共模块(不能直接访问)
├─Home 前台模块
├─Admin 后台模块
├─... 其他更多模块
├─Runtime 默认运行时目录(可以设置)
默认情况下,只要应用目录下面存在模块目录,该模块就可以访问,只有当你希望禁止某些模块或者仅允许模块访问的时候才需要进行模块列表的相关设置。
每个模块是相对独立的,其目录结构如下:
├─Module 模块目录
│ ├─Conf 配置文件目录
│ ├─Common 公共函数目录
│ ├─Controller 控制器目录
│ ├─Model 模型目录
│ ├─Logic 逻辑目录(可选)
│ ├─Service Service目录(可选)
│ ... 更多分层目录可选
│ └─View 视图目录
由于采用多层的MVC机制,除了Conf和Common目录外,每个模块下面的目录结构可以根据需要灵活设置和添加,所以并不拘泥于上面展现的目录
二、环境配置
新建数据库
先在新建数据库名为thinkphp3,其中添加两个字段username和password
添加字段
添加一条数据username:admin,password:admin
配置数据连接
然后修改thinkphp配置文件:
将thinkphp-->conf-->convention.php中的关于数据库配置的内容复制到Application-->Common-->Conf-->config.php中并填写相关信息。
/* 数据库设置 */
'DB_TYPE' => 'mysql', // 数据库类型
'DB_HOST' => '127.0.0.1', // 服务器地址
'DB_NAME' => 'thinkphp3', // 数据库名
'DB_USER' => 'root', // 用户名
'DB_PWD' => 'root', // 密码
'DB_PORT' => '3306', // 端口
'DB_PREFIX' => 'thinkphp_', // 数据库表前缀
'DB_PARAMS' => array(), // 数据库连接参数
'DB_DEBUG' => TRUE, // 数据库调试模式 开启后可以记录SQL日志
'DB_FIELDS_CACHE' => true, // 启用字段缓存
'DB_CHARSET' => 'utf8', // 数据库编码默认采用utf8
'DB_DEPLOY_TYPE' => 0, // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
'DB_RW_SEPARATE' => false, // 数据库读写是否分离 主从式有效
'DB_MASTER_NUM' => 1, // 读写分离后 主服务器数量
'DB_SLAVE_NO' => '', // 指定从服务器序号
/* 数据缓存设置 */
'DATA_CACHE_TIME' => 0, // 数据缓存有效期 0表示永久缓存
'DATA_CACHE_COMPRESS' => false, // 数据缓存是否压缩缓存
'DATA_CACHE_CHECK' => false, // 数据缓存是否校验缓存
'DATA_CACHE_PREFIX' => '', // 缓存前缀
'DATA_CACHE_TYPE' => 'File', // 数据缓存类型,支持:File|Db|Apc|Memcache|Shmop|Sqlite|Xcache|Apachenote|Eaccelerator
'DATA_CACHE_PATH' => TEMP_PATH,// 缓存路径设置 (仅对File方式缓存有效)
'DATA_CACHE_KEY' => '', // 缓存文件KEY (仅对File方式缓存有效)
'DATA_CACHE_SUBDIR' => false, // 使用子目录缓存 (自动根据缓存标识的哈希创建子目录)
'DATA_PATH_LEVEL' => 1, // 子目录缓存级别
测试数据库是否连接成功:
打开Application-->Home-->Controller-->IndexController.class.php
在其中加入测试代码:
public function test(){
$data = M('user')->where('id=1')->select();
dump($data);
然后访问http://127.0.0.1/thinkphp_3.2.3/index.php/home/index/test,输出信息则说明数据库连接成功。
array(1) {
[0] => array(3) {
["id"] => string(1) "1"
["username"] => string(5) "admin"
["password"] => string(5) "admin"
}
}
开启调试,在配置文件中加入如下配置:
'SHOW_ERROR_MSG' => true, // 显示错误信息
参考官方文档:
https://www.kancloud.cn/manual/thinkphp/1825
再次访问:http://127.0.0.1/thinkphp_3.2.3/index.php/home/index/test,点击右下角图标即可打开调试窗口。
thinkphp访问
官方手册:https://www.kancloud.cn/manual/thinkphp/1697
入口文件是应用的单一入口,对应用的所有请求都定向到应用入口文件,系统会从URL参数中解析当前请求的模块、控制器和操作:
http://serverName/index.php/模块/控制器/操作
URI模式的配置在ThinkPHP--》Conf--》convention.php中进行配置。
/*表示URL区分大小写 true则表示不区分大小写*/
'URL_MODEL' => 1,
// URL访问模式,可选参数0、1、2、3,代表以下四种模式:
0 (普通模式);
1 (PATHINFO 模式);
2 (REWRITE 模式);
3 (兼容模式)
默认为PATHINFO 模式
在默认的PATHINFO 模式下,我们也可以使用普通模式的方式进行访问:
http://127.0.0.1/thinkphp_3.2.3/index.php?m=home&c=index&a=test
其中参数解释如下:
m:即Module,模式
c:controller,控制器
a:action,方法
URL模式
如果我们直接访问入口文件的话,由于URL中没有模块、控制器和操作,因此系统会访问默认模块(Home)下面的默认控制器(Index)的默认操作(index),因此下面的访问是等效的:
http://serverName/index.php
http://serverName/index.php/Home/Index/index
三、Thinkphp控制器
3.1、控制器的定义
ThinkPHP的控制器是一个类,而操作则是控制器类的一个公共方法(Public function)。
参考:https://www.kancloud.cn/manual/thinkphp/1713
php
namespace Home\Controller; //使用Home\Controller控制器,对应的目录文件
use Think\Controller; //表示引入 Think\Controller 类库.
class IndexController extends Controller {
public function hello(){
echo 'hello,thinkphp!';
}
}
Home\IndexController
类就代表了Home模块下的Index控制器,而hello操作就是Home\IndexController
类的hello(公共)方法。
当访问 http://serverName/index.php/Home/Index/hello
后会输出:
hello,thinkphp!
3.2、控制器操作
A("[模块/]控制器标志")实例化控制器对象。
R("[模块/]控制器标志/操作方法")实例化控制器对象同时调用指定对象。
3.2.1 A方法
跨控制器实例化后,再调用被实例化对象的方法
UserControllerclass.php
$User = A(User); $User->index();
3.2.2 R方法
UserControllerclass.php
R('$User->index()');
示例:
UserController.class.php内容如下
php
namespace Home\Controller;
use Think\Controller;
class UserController extends Controller {
public function index(){
echo 'User Controller';
}
}
使用Index控制器去调用User控制器中的方法
public function getUserIndex(){
$User = A('User');
$User -> index(); // A方法
//R('User/index'); // R方法
}
3.2.3 Action参数绑定
参考:https://www.kancloud.cn/manual/thinkphp/1715
Action参数绑定是通过直接绑定URL地址中的变量作为操作方法的参数,可以简化方法的定义甚至路由的解析。
Action参数绑定功能默认是开启的,其原理是把URL中的参数(不包括模块、控制器和操作名)和操作方法中的参数进行绑定。
要启用参数绑定功能,首先确保你开启了URL_PARAMS_BIND
设置:
'URL_PARAMS_BIND' => true, // URL变量绑定到操作方法作为参数
BlogController.class.php
php
namespace Home\Controller;
use Think\Controller;
class BlogController extends Controller{
public function read($id){
echo 'id='.$id;
}
}
?>
http://127.0.0.1/thinkphp_3.2.3/index.php/Home/Blog/read/id/100
id=100
3.2.4 获取变量
php里面所有的原生语法都支持以下方法获取变量:
$id = $_GET['id']; // 获取get变量
$name = $_POST['name']; // 获取post变量
$value = $_SESSION['var']; // 获取session变量
$name = $_COOKIE['name']; // 获取cookie变量
$file = $_SERVER['PHP_SELF']; // 获取server变量
传统获取方式因为没有统一的安全处理机制,后期如果调整的话,改起来会比较麻烦。
I方法是ThinkPHP用于更加方便和安全的获取系统输入变量,可以用于任何地方,用法格式如下:
I('变量类型.变量名/修饰符',['默认值'],['过滤方法或正则'],['额外数据源'])
public function getUser(){
$id = I('id','1','intval');
dump($id);
}
当存在参数赋值时
http://127.0.0.1/thinkphp_3.2.3/index.php/Home/Index/Getuser/id/100
int(100)
http://127.0.0.1/thinkphp_3.2.3/index.php/Home/Index/Getuser/id/
string(1) "1"
3.2.5 判断请求类型
https://www.kancloud.cn/manual/thinkphp/1722
常量 | 说明 |
---|---|
IS_GET | 判断是否是GET方式提交 |
IS_POST | 判断是否是POST方式提交 |
IS_PUT | 判断是否是PUT方式提交 |
IS_DELETE | 判断是否是DELETE方式提交 |
IS_AJAX | 判断是否是AJAX提交 |
REQUEST_METHOD | 当前提交类型 |
个别情况下,你可能需要在表单里面添加一个隐藏域,告诉后台属于ajax方式提交,默认的隐藏域名称是ajax(可以通过VAR_AJAX_SUBMIT配置),如果是JQUERY类库的话,则无需添加任何隐藏域即可自动判断。
3.2.6 插件控制器
https://www.kancloud.cn/manual/thinkphp/1725
3.2.3版本开始,插件控制器默认和模块同级
http://serverName/Home/info/index/addon/SystemInfo
3.2.3版本中,实际访问的插件控制器是:
Addon/SystemInfo/Controller/InfoController.class.php