一、ThinkPHP中的实用项
在开发的时候我们往往会需要一些开发的错误,需要去解决错误,一般这个时候我们比较需要借助于开发工具/调试工具,比如说浏览器自带的“审核元素”,在ThinkPHP中系统为了方便我们在开发的时候对代码进行调试,也封装了一系列的调试方法:
–跟踪信息
–两种模式
–Sql调试
–性能调试
1、跟踪信息
跟踪信息:就是查询/展示系统的执行相关状况。
在ThinkPHP中跟踪信息默认是关闭的,如果需要使用,则需要开启,可以通过配置项:SHOW_PAGE_TRACE。
上述的配置项在主配置文件中是不存在的(在ThinkPHP中除了主配置文件中已经列出的配置项外,还存在一些零星的配置项,这些配置项在主配置文件中不存在,但是其他地方有使用),需要使用的话可以自己在配置文件中定义。
开始之后进行访问右下角会出现一个logo 可以点击 并且用来调试
在当前模式下,基本信息中的数据:
2、两种模式
在ThinkPHP系统为了方便开发,提供了以下两种模式 :开发/调试模式、生产模式。
调试模式:是指在开发调试阶段所使用的模式,错误信息比较详细;
生产模式:是指项目上线的时候所使用的模式,错误信息比较模糊;
在ThinkPHP中两种模式其默认值默认是生产模式,其配置项名字叫做APP_DEBUG。定义的位置在入口文件中:
当app_debug为false的时候表示开启生产模式。
当app_debug为true的时候表示开启调试模式。
调式模式下的访问:
生产模式下的访问:
在生产模式里面的效率比调试模式模式要高 因为在生产模式下系统函数库文件functions.php、系统的配置文件、应用配置文件没有被加载,但是多了一个common~runtime.php文件(没有被加载的配置文件的配置项都放到了新增文件中)。
3.SQL调试
在开发的时候,难免会遇到sql的错误,这个时候需要对sql进行调试,因为ThinkPHP在执行CURD操作的时候是让开发者写方法,并不是很直观的sql:
$model -> getLastSql();
表达的含义:获取当前模型中最后一条成功执行的sql语句。
案例:使用getLastSql方法获取最后一个sql语句。
上述的getLastSql方法在写的不方便,所以ThinkPHP3.2版本之后,系统增加了一个别名方法:_sql();
$model -> _sql();
所以,上述案例代码可以写成:
二、AR模式
1、介绍
AR模式即Active Record模式,是一个对象-关系映射(ORM)技术。每个AR 类代表一张数据表(或视图),数据表(或视图)的字段在 AR 类中体现为类的属性,一个AR 实例则表示表中的一行。
AR模式的核心:三个映射/对应
AR类 ==== 表 (模型类关联了数据表)
AR类的属性 ==== 表的字段
AR类实例 ==== 表的记录
AR模式的语法格式:
AR模式在ThinkPHP中的典型的应用:CURD操作。
//实例化模型
$model = M(关联的表);
//字段映射到属性
$model -> 属性/表中字段 = 字段值;
$model -> 属性/表中字段 = 字段值;
…
//AR实例(操作)映射到表中记录
$model -> CURD操作; CURD操作没有参数
2、AR模式的CURD操作
增加操作:
通过数据表中的记录,可以得知,其返回值和之前add的操作返回值是一样的,都表示新增记录的主键id。
问题1:难道父类模型中真的有name、pid、sort、remark属性么?
答:通过观察父类模型的底层实现,我们找到了一个特殊的魔术方法__set,可以参考php手册:
赋值成功之后可以打印模型查看到模型中存在属性data:
问题2:为什么add方法没有参数也能执行添加操作?
答:通过问题1中的解答,我们可以得知如果使用ar模式的话,data属性是有值,然后通过查看add方法的底层实现:
其中判断是否给add方法传递参数,如果没有传递,则使用父类模型中data属性中值,而data属性中的值恰恰就是问题1中的数据。
修改操作 与上述操作一样都是通过AR模式 映射 (但是这里需要注意的是 修改的时候一定要有主键)
并且返回值和之前的save传递数组一样,表示受到影响的行数。
查询操作
在ThinkPHP中,AR模式没有查询操作。这里的查询操作还是使用之前的select和find方法。
删除操作
需要注意:删除的时候必须需要指定主键信息
案例:使用AR模式删除表中的数据。
补充说明
在AR模式中U、D操作必须需要指定主键信息,但是有一种情况下可以不指定主键也能执行U、D操作:在之前有做过查询语句,则后面如果没有指定主键,会操作当前查询到的记录。
自己试下了下select 却不会 find能够这样
删除:
ThinkPHP中的辅助方法(重点)
在原生的sql语句中除了我们目前所使用的基本的操作之后,还有类似于group、where、order、limit等等这样的子句。在后期如果需要用到上述的一些子句方法,以目前的知识储备肯定是不行的,所以ThinkPHP封装了相应的子句方法:
where 表示限制查询的条件
limit 表示限制输出的条数
field 表示限制输出的字段 也就是select id,name,pid这样的语句
order 表示按照指定的字段进行指定的排序
group 表示按照指定的字段进行分组查询
1、where方法
作用:限制查询的条件。
在原生的sql语句中:select 字段 from 表 where 条件;
在ThinkPHP中系统封装了一个where方法来实现在原生的sql语句中where效果。
语法:
$model -> where(条件表达式); //在ThinkPHP中条件表达式支持字符串形式也支持数组形式,推荐使用字符串形式。
$model -> CURD操作;
案例:使用where方法查询部门表中部门id大于20的数据。
使用原生的sql:select * from sp_dept where id > 20;
2、limit方法
作用:限制输出的条数。(典型的应用:数据分页)
在原生的sql语句中:select 字段 from 表 where 条件 limit 限制的条数;
在ThinkPHP中系统提供了limit方法来实现原生的sql语句中限制条数的效果:
第一种:$model -> limit(n); //n表示大于0的数字,表示输出表中的前n行
第二种:$model -> limit(起始位置,偏移量/长度); //表示从第起始位置开始,往后查询指定长度的记录数,在实际使用的时候该种方法还支持写成$model -> limit(‘起始位置,偏移量’);
案例:使用limit语法格式来实现查询表中的数据限制。
3、field方法
作用:限制输出的结果集字段。
语法:
$model -> field(‘字段1,字段2,字段3,字段4[ as 别名]….’); //参数也就是select之后到from之前的那一串字符串。
案例:使用field方法来查询部门表中的数据,只要显示id和name就可以。
原生的sql:select id,name from sp_dept;
4、order方法
作用:指按照指定的字段进行指定规则的排序。
在原生的sql语法中使用是:order by 字段 排序规则(升序asc/降序desc)。
语法:
$model -> order(‘字段名 排序规则’);
案例:使用order方法查询部门表中的数据,并且按照id进行降序排列。
原生的sql:select * from sp_dept order by id desc;
5、group方法
作用:分组查询。
在ThinkPHP中group分组可以使用group方法来实现:
$model -> group(‘字段名’);
案例:使用group的方法去查询部门表,要求查询出部门名称和出现的次数。
原生的sql:select name,count(*) as count from sp_dept group by name;
使用辅助方法实现上述的sql:
因为上述的原生sql使用了限制字段和分组查询,所以在ThinkPHP中光靠group方法没有办法实现案例要求,还需要配合filed方法来实现:
四、连贯操作(重点)
连贯操作:所谓连贯操作就是将辅助方法全部写在一行上的写法,这样的形式叫做连贯操作。
也就是如下的形式:
$model -> where() -> limit() -> order -> field() -> select();
注意点:辅助方法的顺序,在连贯操作中没有要求,只要符合模型在最前面,CURD方法在最后面即可。
解疑:连贯操作上的辅助方法啊为什么可以写在一行上呢?
答:原因就是每一个辅助方法最后的返回值都是
t
h
i
s
,
而
this,而
this,而this是指当前的模型类,由模型类去调用后续的辅助方法,这个是可以行得通的。这也是为什么要求CURD方法必须放在最后的原因。
在以后的开发过程中,不管是自己写的代码还是别人写的代码,都会遵循使用连贯操作的形式来替代每一个辅助方法单独一行的写法。
五、ThinkPHP中的统计查询
在ThinkPHP中系统提供以下几个查询方法的使用,方便于在后期需要做统计的使用。
count() 表示查询表中总的记录数
max() 表示查询某个字段的最大值
min() 表示查询某个字段的最小值
avg() 表示查询某个字段的平均值
sum() 表示求出某个字段的总和
1、count方法
语法:$model -> [where() ->] count();
案例:查询出部门表中的总的记录数。
2、max方法
语法:
$model -> max(‘字段名’);
案例:查询部门表中id最大的部门的id。
在以后实际开发的时候有一个应用:通过max方法查询最后注册的会员id。
3.min方法
与上述操作都一样
4、avg方法
与上述操作都一样
5、sum方法
与上述操作都一样
六、扩展(1)
1、fetchSql
前面我们介绍了sql调试的一个方法getLastSql或者别名_sql(),但是这个方法要求最后一条成功执行的sql,所以如果拿这个方法来调试sql,只能是调试逻辑错误,并不能拿来调试语法错误,所以这里给大家介绍一个新的sql调试方法:fetchSql()。
语法:
$model -> where() -> limit() … -> order() -> fetchSql(true) -> CURD操作;
FetchSql方法使用的时候可以完全看作是一个辅助方法,所以要求必须在model之后,在CURD操作之前,顺序无所谓。FetchSql方法只能在ThinkPHP3.2.3版本之后使用。
去控制器里面测试以下
说明:通过跟踪信息和返回值,我们可以发现,使用fetchSql之后原有的连贯操作没有被执行(在跟踪信息中没有sql显示),而是直接将连贯操作的语法组成的sql语句给返回。
处理表单信息的提交操作
改写add方法,判断是否是post请求,如果是,则处理表单的提交,如果不是则展示模版。
扩展:如果判断请求是否是post?
答:要是在以前,我们可以使用if(
P
O
S
T
)
来
判
断
,
但
是
在
T
h
i
n
k
P
H
P
中
系
统
为
我
们
封
装
了
几
个
比
较
使
用
的
常
量
,
可
以
直
接
用
常
量
来
判
断
,
常
量
常
见
的
如
下
:
I
S
P
O
S
T
如
果
请
求
是
p
o
s
t
,
则
I
S
P
O
S
T
的
值
是
t
r
u
e
,
否
则
是
f
a
l
s
e
I
S
G
E
T
I
S
A
J
A
X
如
果
请
求
是
a
j
a
x
,
则
I
S
A
J
A
X
的
值
是
t
r
u
e
,
否
则
是
f
a
l
s
e
I
S
C
G
I
I
S
P
U
T
…
关
于
数
据
接
收
的
说
明
:
在
之
前
我
们
使
用
的
时
候
_POST)来判断,但是在ThinkPHP中系统为我们封装了几个比较使用的常量,可以直接用常量来判断,常量常见的如下: IS_POST 如果请求是post,则IS_POST的值是true,否则是false IS_GET IS_AJAX 如果请求是ajax,则IS_AJAX的值是true,否则是false IS_CGI IS_PUT … 关于数据接收的说明: 在之前我们使用的时候
POST)来判断,但是在ThinkPHP中系统为我们封装了几个比较使用的常量,可以直接用常量来判断,常量常见的如下:ISPOST如果请求是post,则ISPOST的值是true,否则是falseISGETISAJAX如果请求是ajax,则ISAJAX的值是true,否则是falseISCGIISPUT…关于数据接收的说明:在之前我们使用的时候_POST来接收数据,在ThinkPHP中,我们可以使用I方法(快速方法)来接收数据,I方法可以接收任何类型的输入(post、get、request、put等等),并且系统默认自带防sql注入的方法(使用php内置的函数htmlspecialchars)。
语法:
变量类型就是类似get、post等等。
变量名就是指
G
E
T
或
者
_GET或者
GET或者_POST中具体元素下标。
默认值:是当使用过滤方法之后原先的内容如果变成了空字符串,则会使用默认值来代替。
过滤方法:是对ThinkPHP默认提供的htmlspecialchars的补充,函数名可以是php内置的,也可以是函数库中的。
额外的说明:如果想接收整个数组则呢么呢?
如果想接收全部数据,则可以不写变量名,可以写成I(‘get.’);