复习ThinkPHP 3.2框架

该篇以ThinkPHP3.2入手,整理常用的ThinkPHP部分,如数据库操作!(推荐看官方手册)

## 第1章 课程简介 ##
本章简要介绍了本门课程的课程内容以及学习目标。
### 1-1 快速入门ThinkPHP框架课程简介
图01

推荐10款PHP框架
https://www.helloweba.net/news/557.html

课程主要内容:
– 理解MVC思想与框架思维
– ThinkPHP基础知识
– ThinkPHP数据库的操作
– 基于ThinkPHP的博客文章系统

图2

## 第2章 关于MVC ##
简要介绍MVC的工作原理。
### 2-1 MVC简析
MVC是一种设计模式,它强制性的使应用程序的输入、处理和输出分开。使用MVC应用程序被分成三个核心部件:模型、视图、控制器,它们各自处理自己的任务。

模型:处理数据和业务逻辑
视图:通过布局向用户展示数据
控制器:接收用户请求,并调用相应的模型处理

图3

图4

## 第3章 使用ThinkPHP框架建立项目 ##
本章通过介绍ThinkPHP框架的安装和引用,以及对项目目录结构的说明,让大家对ThinkPHP有一个充分的了解,并学会Hello World页面的实现。
### 3-1 框架简介
框架是程序结构代码的集合,而不是业务逻辑代码。集合中包含了许多类、函数和功能包。这个集合是按照一定标准组成的功能体系。体系有很多设计模式,比如MVC等。

### 3-2 ThinkPHP框架学习流程
1、建立一个简单项目,了解项目的运行流程

2、了解TP的URL模式,建立自定义函数库

3、模板技术,调试模式和运行状态

4、数据的常用操作

### 3-3 ThinkPHP框架简介
– 国产、开源、面向对象、MVC框架
– 简单易用,查询语言丰富,详尽的中文文档
– 官网:www.thinkphp.cn

### 3-4 关于单一入口
在一个网站中,所有的请求都是指向同一个脚本文件的。

好处:项目结构规范,控制灵活,更加安全

### 3-5 使用ThinkPHP创建一个项目

Select Code
1
2
3
4
5
// 定义应用目录
define('APP_PATH','./App/');

// 引入ThinkPHP入口文件
require './ThinkPHP/ThinkPHP.php';

### 3-6 ThinkPHP框架目录结构解析
http://document.thinkphp.cn/manual_3_2.html#directory_structure

其中框架目录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 框架入口文件

## 第4章 ThinkPHP框架的简单操作 ##
本章主要讲解框架的运行原理、ThinkPHP的URL模式以及ThinkPHP的配置文件等内容,旨在让小伙伴们对ThinkPHP框架的基本操作有一个深入的了解和掌握。
### 4-1 ThinkPHP运行流程
http://document.thinkphp.cn/manual_3_2.html#system_process

ThinkPHP框架开发的应用的标准执行流程:

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
用户URL请求
调用应用入口文件(通常是网站的index.php)
载入框架入口文件(ThinkPHP.php)
记录初始运行时间和内存开销
系统常量判断及定义
载入框架引导类(Think\Think)并执行Think::start方法进行应用初始化
设置错误处理机制和自动加载机制
调用Think\Storage类进行存储初始化(由STORAGE_TYPE常量定义存储类型)
部署模式下如果存在应用编译缓存文件则直接加载(直接跳转到步骤22)
读取应用模式(由APP_MODE常量定义)的定义文件(以下以普通模式为例说明)
加载当前应用模式定义的核心文件(普通模式是 ThinkPHP/Mode/common.php)
加载惯例配置文件(普通模式是 ThinkPHP/Conf/convention.php)
加载应用配置文件(普通模式是 Application/Common/Conf/config.php)
加载系统别名定义
判断并读取应用别名定义文件(普通模式是 Application/Common/Conf/alias.php)
加载系统行为定义
判断并读取应用行为定义文件(普通模式是 Application/Common/Conf/tags.php)
加载框架底层语言包(普通模式是 ThinkPHP/Lang/zh-cn.php)
如果是部署模式则生成应用编译缓存文件
加载调试模式系统配置文件(ThinkPHP/Conf/debug.php)
判断并读取应用的调试配置文件(默认是 Application/Common/Conf/debug.php)
判断应用状态并读取状态配置文件(如果APP_STATUS常量定义不为空的话)
检测应用目录结构并自动生成(如果CHECK_APP_DIR配置开启并且RUNTIME_PATH目录不存在的情况下)
调用Think\App类的run方法启动应用
应用初始化(app_init)标签位侦听并执行绑定行为
判断并加载动态配置和函数文件
调用Think\Dispatcher::dispatch方法进行URL请求调度
自动识别兼容URL模式和命令行模式下面的$_SERVER['PATH_INFO']参数
检测域名部署以及完成模块和控制器的绑定操作(APP_SUB_DOMAIN_DEPLOY参数开启)
分析URL地址中的PATH_INFO信息
获取请求的模块信息
检测模块是否存在和允许访问
判断并加载模块配置文件、别名定义、行为定义及函数文件
判断并加载模块的动态配置和函数文件
模块的URL模式判断
模块的路由检测(URL_ROUTER_ON开启)
PATH_INFO处理(path_info)标签位侦听并执行绑定行为
URL后缀检测(URL_DENY_SUFFIX以及URL_HTML_SUFFIX处理)
获取当前控制器和操作,以及URL其他参数
URL请求调度完成(url_dispatch)标签位侦听并执行绑定行为
应用开始(app_begin)标签位侦听并执行绑定行为
调用SESSION_OPTIONS配置参数进行Session初始化(如果不是命令行模式)
根据请求执行控制器方法
如果控制器不存在则检测空控制器是否存在
控制器开始(action_begin)标签位侦听并执行绑定行为
默认调用系统的ReadHtmlCache行为读取静态缓存(HTML_CACHE_ON参数开启)
判断并调用控制器的_initialize初始化方法
判断操作方法是否存在,如果不存在则检测是否定义空操作方法
判断前置操作方法是否定义,有的话执行
Action参数绑定检测,自动匹配操作方法的参数
如果有模版渲染(调用控制器display方法)
视图开始(view_begin)标签位侦听并执行绑定行为
调用Think\View的fetch方法解析并获取模版内容
自动识别当前主题以及定位模版文件
视图解析(view_parse)标签位侦听并执行绑定行为
默认调用内置ParseTemplate行为解析模版(普通模式下面)
模版引擎解析模版内容后生成模版缓存
模版过滤替换(template_filter)标签位侦听并执行绑定行为
默认调用系统的ContentReplace行为进行模版替换
输出内容过滤(view_filter)标签位侦听并执行绑定行为
默认调用系统的WriteHtmlCache行为写入静态缓存(HTML_CACHE_ON参数开启)
调用Think\View类的render方法输出渲染内容
视图结束(view_end)标签位侦听并执行绑定行为
判断后置操作方法是否定义,有的话执行
控制器结束(action_end)标签位侦听并执行绑定行为
应用结束(app_end)标签位侦听并执行绑定行为
执行系统的ShowPageTrace行为(SHOW_PAGE_TRACE参数开启并且不是AJAX请求)
日志信息存储写入

### 4-2 ThinkPHP的配置文件
配置文件是自动加载的,加载的顺序是:
惯例配置->应用配置->模式配置->调试配置->状态配置->模块配置->扩展配置->动态配置

Select Code
1
2
3
4
5
6
7
8
惯例配置文件(位于ThinkPHP/Conf/convention.php)。
应用配置文件也就是调用所有模块之前都会首先加载的公共配置文件(默认位于Application/Common/Conf/config.php)。
为应用模式(后面会有描述)单独定义配置文件,文件命名规范是: Application/Common/Conf/config_应用模式名称.php(仅在运行该模式下面才会加载)
开启调试模式后,调试配置文件(位于ThinkPHP/Conf/debug.php)和应用调试配置文件(位于Application/Common/Conf/debug.php)
状态配置:你需要在公司和家里分别设置不同的数据库测试环境。那么可以这样处理,在公司环境中,我们在入口文件中定义:define('APP_STATUS','office');那么就会自动加载该状态对应的配置文件(位于Application/Common/Conf/office.php)。
模块配置:每个模块会自动加载自己的配置文件(位于Application/当前模块名/Conf/config.php)
扩展配置:'LOAD_EXT_CONFIG' => 'user,db' 
动态配置:C('参数名称','新的参数值'),动态配置赋值仅对当前请求有效,不会对以后的请求造成影响。

获取已经设置的参数值:C(‘参数名称’)
C方法也可以用于读取二维配置:C(‘USER_CONFIG.USER_TYPE’)

### 4-3 ThinkPHP的URL模式
URL参数中解析当前请求的模块、控制器和操作,这是3.2版本的标准URL格式。

http://serverName/index.php/模块/控制器/操作

ThinkPHP框架的URL是区分大小写(主要是针对模块、控制器和操作名,不包括应用参数)的。当URL_CASE_INSENSITIVE设置为true的时候表示URL地址不区分大小写,这个也是框架在部署模式下面的默认设置。

URL模式 URL_MODEL设置
– 普通模式 0
– PATHINFO模式 1
– REWRITE模式 2
– 兼容模式 3

  • 普通模式:http://localhost/?module=home&controller=user&action=login&var=value
  • PATHINFO模式下面的URL访问地址是: http://localhost/index.php/home/user/login/var/value/
  • REWRITE模式:http://localhost/home/user/login/var/value
  • 兼容模式:http://localhost/?s=/home/user/login/var/value

URL生成:U(‘地址表达式’,[‘参数’],[‘伪静态后缀’],[‘显示域名’])
echo U(‘Index/index’, ”, ‘html’, ‘localhost’); //http://localhost/index.php/Home/Index/index.html

### 4-4 隐藏index.php文件
http://document.thinkphp.cn/manual_3_2.html#url_rewrite

### 4-5 URL伪静态
‘URL_HTML_SUFFIX’ => ‘html’, // URL伪静态后缀设置

### 4-6 自定义函数库
\App\Common\Common\function.php

## 第5章 ThinkPHP框架的模板技术 ##
本章主要讲解了ThinkPHP框架的模板的使用以及模板引擎的选择。
### 5-1 建立项目模板
// 不带任何参数 自动定位当前操作的模板文件 $this->display();

创建首页文件路径:’./App/Home/View/Index/index.html’

### 5-2 模板的赋值和输出
$this->assign(‘name’,$value);
// 下面的写法是等效的
$this->name = $value;

采用内置的模板引擎,可以使用: {$name} [ {$email} {$phone} ] 输出同样的内容。

### 5-3 ThinkPHP模板引擎介绍
ThinkPHP内置了一个基于XML的性能卓越的模板引擎 ThinkTemplate,这是一个专门为ThinkPHP服务的内置模板引擎。

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
'TMPL_ENGINE_TYPE'      =>  'Think',     // 默认模板引擎 以下设置仅对使用Think模板引擎有效
'TMPL_CACHFILE_SUFFIX'  =>  '.php',      // 默认模板缓存后缀
'TMPL_DENY_FUNC_LIST'   =>  'echo,exit',    // 模板引擎禁用函数
'TMPL_DENY_PHP'         =>  false, // 默认模板引擎是否禁用PHP原生代码
'TMPL_L_DELIM'          =>  '{',            // 模板引擎普通标签开始标记
'TMPL_R_DELIM'          =>  '}',            // 模板引擎普通标签结束标记
'TMPL_VAR_IDENTIFY'     =>  'array',     // 模板变量识别。留空自动判断,参数为'obj'则表示对象
'TMPL_STRIP_SPACE'      =>  true,       // 是否去除模板文件里面的html空格与换行
'TMPL_CACHE_ON'         =>  true,        // 是否开启模板编译缓存,设为false则每次都会重新编译
'TMPL_CACHE_PREFIX'     =>  '',         // 模板缓存前缀标识,可以动态改变
'TMPL_CACHE_TIME'       =>  0,         // 模板缓存有效期 0 为永久,(以数字为值,单位:秒)
'TMPL_LAYOUT_ITEM'      =>  '{__CONTENT__}', // 布局模板的内容替换标识
'LAYOUT_ON'             =>  false, // 是否启用布局
'LAYOUT_NAME'           =>  'layout', // 当前布局名称 默认为layout

// Think模板引擎标签库相关设定
'TAGLIB_BEGIN'          =>  '<',  // 标签库标签开始标记
'TAGLIB_END'            =>  '>',  // 标签库标签结束标记
'TAGLIB_LOAD'           =>  true, // 是否使用内置标签库之外的其它标签库,默认自动检测
'TAGLIB_BUILD_IN'       =>  'cx', // 内置标签库名称(标签使用不必指定标签库名称),以逗号分隔 注意解析顺序
'TAGLIB_PRE_LOAD'       =>  '',   // 需要额外加载的标签库(须指定标签库名称),多个以逗号分隔

### 5-4 ThinkPHP模板引擎之变量输出和运算
模板中使用:Hello,{$name}
默认值输出:{$user.nickname|default=”这家伙很懒,什么也没留下”}
运算符:{$user[‘score’]+10} //在使用运算符的时候,不再支持点语法和常规的函数用法

### 5-5 ThinkPHP模板引擎之调用函数和系统参数
对模板变量使用函数:{$data.name|md5}
函数有多个参数:{$create_time|date=”y-m
支持多个函数过滤,多个函数之间用“|”分割即可:{$name|md5|strtoupper|substr=0,3} 或 {:substr(strtoupper(md5($name)),0,3)}

系统变量:{$Think.server.script_name}

### 5-6 ThinkPHP模板引擎之volist和foreach循环
循环输出系统变量:

Select Code
1
2
3
<volist name="list" id="vo">
{$vo.id}:{$vo.name}<br/>
</volist>
Select Code
1
2
3
<volist name="list" id="vo" key="k" >
{$k}.{$vo.name}
</volist>

没有指定key属性的话,默认使用循环变量i

### 5-7 ThinkPHP模板引擎之FOR循环

Select Code
1
2
<for start="开始值" end="结束值" comparison="" step="步进值" name="循环变量名" >
</for>

开始值和结束值是必须,其他是可选;
comparison 的默认值是lt;

### 5-8 ThinkPHP模板引擎之IF判断

Select Code
1
2
3
4
<if condition="($name eq 1) OR ($name gt 100) "> value1
<elseif condition="$name eq 2"/>value2
<else /> value3
</if>

### 5-9 ThinkPHP模板引擎之Switch判断

Select Code
1
2
3
4
5
<switch name="变量" >
<case value="值1" break="0或1">输出内容1</case>
<case value="值2">输出内容2</case>
<default />默认情况
</switch>

### 5-10 ThinkPHP模板引擎之比较标签
标签 含义
eq或者 equal 等于
neq 或者notequal 不等于
gt 大于
egt 大于等于
lt 小于
elt 小于等于
heq 恒等于
nheq 不恒等于

### 5-11 ThinkPHP模板引擎之区间标签
范围判断标签包括in notin between notbetween四个标签,都用于判断变量是否中某个范围。

### 5-12 ThinkPHP模板引擎之三元运算符

Select Code
1
2
{$status?'正常':'错误'}
{$info['status']?$info['msg']:$info['error']}

注意:三元运算符中暂时不支持点语法。

### 5-13 ThinkPHP模板引擎之案例实战

## 第6章 ThinkPHP框架的调试模式 ##
本章主要讲解了调试模式的用途以及如何使用调试模式进行相关的开发。
### 6-1 ThinkPHP的调试方法
开启调试模式:define(‘APP_DEBUG’,True);
在开启调试模式的状态下,系统会首先导入框架默认的调试模式配置文件,该文件位于系统目录的Conf\debug.php。

显示页面Trace信息
‘SHOW_PAGE_TRACE’ =>true,

系统提供了G方法可以很方便的获取某个区间的运行时间和内存占用情况

除了使用php内置的var_dump和print_r之外,内置了一个对浏览器友好的dump方法,用于输出变量的信息到浏览器查看。

默认情况下只是在调试模式记录日志,要在部署模式开启日志记录,必须在配置中开启LOG_RECORD参数,以及可以在应用配置文件中配置需要记录的日志级别
‘LOG_RECORD’ => true, // 开启日志记录

## 第7章 数据库操作(一) ##
本章主要讲解了ThinkPHP框架独特的CURD的操作方式,以及在查询数据库时所用的连贯操作、视图模型等内容。
### 7-1 连接数据库

Select Code
1
2
3
4
5
6
7
8
9
10
//数据库配置信息
'DB_TYPE'   => 'mysql', // 数据库类型
'DB_HOST'   => 'localhost', // 服务器地址
'DB_NAME'   => 'thinkphp', // 数据库名
'DB_USER'   => 'root', // 用户名
'DB_PWD'    => '123456', // 密码
'DB_PORT'   => 3306, // 端口
'DB_PREFIX' => 'think_', // 数据库表前缀 
'DB_CHARSET'=> 'utf8', // 字符集
'DB_DEBUG'  =>  TRUE, // 数据库调试模式 开启后可以记录SQL日志 3.2.3新增

如果在某个模型类里面定义了connection属性的话,则实例化该自定义模型的时候会采用定义的数据库连接信息。通常用于某些数据表位于当前数据库连接之外的其它数据库。

除了在模型定义的时候指定数据库连接信息外,我们还可以在实例化的时候指定数据库连接信息。

分布式数据库:
内置了分布式数据库的支持,包括主从式数据库的读写分离,但是分布式数据库必须是相同的数据库类型。
配置DB_DEPLOY_TYPE 为1 可以采用分布式数据库支持。
‘DB_HOST’ => ‘192.168.0.1,192.168.0.2’,

对于主从式数据库而言,需要设置读写分离,通过下面的设置就可以:
‘DB_RW_SEPARATE’=>true,
注意:主从数据库的数据同步工作不在框架实现,需要数据库考虑自身的同步或者复制机制。在读写分离的情况下,默认第一个数据库配置是主服务器的配置信息,负责写入数据,设置了DB_MASTER_NUM参数,则可以支持多个主服务器写入。

### 7-2 实例化模型
准备表:

Select Code
1
2
3
4
5
6
7
8
CREATE TABLE IF NOT EXISTS tp_user(
id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(30) NOT NULL DEFAULT '',
age TINYINT(1) NOT NULL DEFAULT 2,
create_time DATETIME NULL DEFAULT CURRENT_TIMESTAMP()
)DEFAULT CHARSET=utf8;

INSERT tp_user(id,name,age) VALUES(NULL,'Ada',10),(NULL,'Lucy',10),(NULL,'May',18),(NULL,'Kitty',22),(NULL,'David',30);

创建模型类文件
参数 实例化的模型文件(假设当前模块为Home)
User 对应的模型类文件的 \Home\Model\UserModel.class.php
UserType 对应的模型类文件的 \Home\Model\UserTypeModel.class.php

D方法实例化
当 \Home\Model\UserModel 类不存在的时候,D函数会尝试实例化公共模块下面的 \Common\Model\UserModel 类。
D方法可以自动检测模型类,如果存在自定义的模型类,则实例化自定义模型类,如果不存在,则会实例化系统的\Think\Model基类,同时对于已实例化过的模型,不会重复去实例化。

Select Code
1
2
$User = D('User');
//相当于 $User = new \Home\Model\UserModel();

M方法实例化模型
D方法实例化模型类的时候通常是实例化某个具体的模型类,如果你仅仅是对数据表进行基本的CURD操作的话,使用M方法实例化的话,由于不需要加载具体的模型类,所以性能会更高。

Select Code
1
2
$User = M('User');
//和用法 $User = new \Think\Model('User'); 等效
Select Code
1
2
3
4
5
$model = new Model('User'); //等同于M('User')
$model = M('User');
$User = D('User');  //实例化Common\Model\UserModel模型
dump($User->getUserInfo(1));
$all_user = $model->select();

实例化空模型类

Select Code
1
2
3
4
5
6
//实例化空模型
$Model = new Model();
//或者使用M快捷方法是等效的
$Model = M();
//进行原生的SQL查询
$Model->query('SELECT * FROM think_user WHERE status = 1');

### 7-3 CURD操作之添加数据

Select Code
1
2
3
4
5
6
7
$User = D('User');
//新增用户
$data = [
	'name' => 'zhangsan',
	'age' => 28
];
$res = $User->add($data);   //返回值为主键id值
Select Code
1
2
3
4
5
6
7
8
$User = D('User');
//批量新增用户
$data = [
	['name' => 'lisi', 'age' => 20],
	['name' => 'wangwu', 'age' => 58],
	['name' => 'liujiu', 'age' => 1]
];
$res = $User->addAll($data);   //返回值为主键id值
Select Code
1
$User->fetchSql(true)->addAll($data) //只生成SQL,不执行

### 7-4 CURD操作之查询数据

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
$user = $User->order('id desc')->find();
echo $User->getLastSql();
echo '<br>';
$user = $User->find();
echo $User->getLastSql();   //SELECT * FROM `tp_user` LIMIT 1
echo '<br>';
$user = $User->order('id desc')->find();
echo $User->getLastSql();   //SELECT * FROM `tp_user` ORDER BY id desc LIMIT 1
echo '<br>';
$user = $User->order('id desc')->select();
echo $User->getLastSql();   //SELECT * FROM `tp_user` ORDER BY id desc
echo '<br>';
$where = [
	'id' => 1,
];
$user = $User->where($where)->order('id desc')->find();
echo $User->getLastSql();   //SELECT * FROM `tp_user` WHERE `id` = 1 ORDER BY id desc LIMIT 1
echo '<br>';
$where = [
	'id' => 1,
	'name' => 'Ada'
];
$user = $User->where($where)->order('id desc')->find();
echo $User->getLastSql();   //SELECT * FROM `tp_user` WHERE `id` = 1 AND `name` = 'Ada' ORDER BY id desc LIMIT 1
echo '<br>';
//连贯操作之字段值
$user = $User->getField('id,name');
echo $User->getLastSql();   //SELECT `id`,`name` FROM `tp_user`
echo '<br>';
$where = [
	'name' => ['like', 'A%'],
];
$user = $User->where($where)->order('id desc')->select();
echo $User->getLastSql();   //SELECT * FROM `tp_user` WHERE `name` LIKE 'A%' ORDER BY id desc 
echo '<br>';
//区间查询
$where = [
	'id' => [
		['gt', 1],
		['lt', 3]
	]
];
$user = $User->where($where)->getField('id,name');
echo $User->getLastSql();   //SELECT `id`,`name` FROM `tp_user` WHERE ( `id` > 1 AND `id` < 3 )
echo '<br>';

### 7-5 CURD操作之更新数据

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
// 更新数据
$data['name'] = 'Think';
$data['update_time'] = date('Y-m-d H:i:s', time());
$res = $User->where(['id' => 1])->save($data);  //1
// 更新字段值
$res = $User->where(['id' => 2])->setField('name', 'after...');
// 自增1
$res = $User->where(['id' => 3])->setInc('age');
// 自增3
$res = $User->where(['id' => 4])->setInc('age', 3);
// 自减
$res = $User->where(['id' => 5])->setDec('age');
dump($res);

### 7-6 CURD操作之删除数据

Select Code
1
2
3
4
5
6
7
8
$where = ['id' => 2];
$res = $User->where($where)->fetchSql(true)->delete();  //DELETE FROM `tp_user` WHERE `id` = 2

$where = ['id' => ['in', [2,3,4]]];
$res = $User->where($where)->fetchSql(true)->delete();  //DELETE FROM `tp_user` WHERE `id` IN (2,3,4)

$where = ['id' => ['lt', 5]];
$res = $User->where($where)->fetchSql(true)->delete();  //DELETE FROM `tp_user` WHERE `id` < 5

## 第8章 数据库操作(二) ##
本章主要讲解了ThinkPHP框架独特的CURD的操作方式,以及在查询数据库时所用的连贯操作、视图模型等内容。
### 8-1 连贯操作之order排序
$Model->where(‘status=1’)->order(‘id desc,status’)->limit(5)->select();

### 8-2 连贯操作之field方法
$Model->field(‘id,nickname as name’)->select();

### 8-3 连贯操作之limit和page方法

Select Code
1
2
3
4
$User->where('status=1')->field('id,name')->limit(10)->select();
$Article->limit('10,25')->select();
$Article->page('1,10')->select(); // 查询第一页数据
$Article->page('2,10')->select(); // 查询第二页数据

### 8-4 连贯操作之group和having方法

Select Code
1
2
3
4
5
$this->field('username,max(score)')->group('user_id')->select();
//SELECT username,max(score) FROM think_score GROUP BY user_id

$this->field('username,max(score)')->group('user_id')->having('count(test_time)>3')->select(); 
//SELECT username,max(score) FROM think_score GROUP BY user_id HAVING count(test_time)>3

### 8-5 多表查询之table方法

Select Code
1
2
3
4
5
$Model->table('think_user')->where('status>1')->select();

$Model->field('user.name,role.title')
->table(array('think_user'=>'user','think_role'=>'role'))
->limit(10)->select();

### 8-6 多表查询之join方法

Select Code
1
2
3
4
5
$Model = M('Artist');
$Model
->join('think_work ON think_artist.id = think_work.artist_id')
->join('think_card ON think_artist.card_id = think_card.id')
->select();

INNER JOIN: 如果表中有至少一个匹配,则返回行,等同于 JOIN
LEFT JOIN: 即使右表中没有匹配,也从左表返回所有的行
RIGHT JOIN: 即使左表中没有匹配,也从右表返回所有的行
FULL JOIN: 只要其中一个表中存在匹配,就返回行

### 8-7 多表查询之union方法

Select Code
1
2
3
4
5
$Model->field('name')
->table('think_user_0')
->union('SELECT name FROM think_user_1')
->union('SELECT name FROM think_user_2')
->select();

//每个union方法相当于一个独立的SELECT语句。

### 8-8 过滤查询之distinct方法
$Model->distinct(true)->field(‘name’)->select();
//SELECT DISTINCT name FROM think_user

## 第9章 关于命名范围的使用 ##
本章介绍了命名范围在实际项目中的使用方法和适用场景。
### 9-1 命名范围的使用
要使用命名范围功能,主要涉及到模型类的_scope属性定义和scope连贯操作方法的使用。

*Common\Model\UserModel.class.php*

Select Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
protected $_scope = array(
	'normal' => [
		'order' => 'id asc',
	],
	'latest' => [
		'order' => 'id desc',
		'limit' => 5,
	]
);

$res = $User->scope('normal')->fetchSql(true)->select();
dump($res); //SELECT * FROM `tp_user` ORDER BY id asc
$res = $User->scope('latest')->fetchSql(true)->select();
dump($res); //SELECT * FROM `tp_user` ORDER BY id desc LIMIT 5