thinkphp3.1.3框架手册
命名规范——————
类文件都是以.class.php为后缀,使用驼峰法命名,并且首字母大写,例如DbMysql.class.php;类名和文件名一致;
函数的命名使用小写字母和下划线的方式,例如 get_client_ip;
方法的命名使用驼峰法,并且首字母小写或者使用下划线“_”,例如 getUserName,_parseType,通常下划线开头的方法属于私有方法;
属性的命名使用驼峰法,并且首字母小写或者使用下划线“_”,例如 tableName、_instance,通常下划线开头的属性属于私有属性;
常量以大写字母和下划线命名,例如 HAS_ONE和 MANY_TO_MANY;
配置参数以大写字母和下划线命名,例如HTML_CACHE_ON;
ThinkPHP的模板文件默认是以.html 为后缀(可以通过配置修改);
项目目录——————
conf(项目配置文件)——config里面的配置参数:
'TMPL_TEMPLATE_SUFFIX' => '.phtml', // 默认模板文件后缀
'URL_MODEL' => 0, //普通模式
采用传统的URL参数模式:
http://serverName/appName/?m=module&a=action&id=1
前端文件的config的配置参数:
分组配置(分组配置文件在Conf/Home或admin/config.php):
'APP_GROUP_LIST' => 'Home,Admin', //项目分组设定
'DEFAULT_GROUP' => 'Home', //默认分组
'TMPL_FILE_DEPR' => '_',分组模板下面模块和操作的分隔符,默认值为“/”
lib(项目类库目录)——通常包括action和model子目录;
Tpl(项目模板目录)——支持模板主题;
如果需要把index.php为后缀,使用驼峰法命名,并且首字母大写,例如DbMysql移动到app的外面,只需要在入口文件中增加项目名称和路径定义;
for example:
定义项目名称:
define('APP_NAME',''Szflame');
定义项目路径:
define('APP_PATH','./Szflame/');
加载框架入口文件
require('../inc/run.php');
部署目录——————
Public:网站公共资源目录(存放网站的css,js和图片等资源);
Uploads:网站上传目录;
admin:后台管理项目目录;(web_adm)
编译缓存目录:
define('RUNTIME_PATH', '../temp/');
开启调试模式:
define('APP_DEBUG', true);
读取配置——————
C('参数名称')//获取已经设置的参数值
动态配置——————
C('参数名称','新的参数值');
函数库——————
系统函数库:位于Common下面的common.php是全局必须加载的基础函数库;
类库——————
类库包括基类库和应用类库,命名规则:
控制器类:模块名+Action;
模型类:模型名+Model;
行为类:行为名+Behavior;
Widget类:Widget名+Widget;
驱动类:引擎名+驱动名;
基类库:目录位于Lib目录
核心类库包下面核心类库:
Action:系统基础控制器类;
Behavior:系统行为基础类;
Model系统基础模型类;
Widget类:系统Widget基础类;
控制器——————
URL模式:ThinkPHP框架基于模块和操作的方式进行访问;
普通模式:在config———config.php里面设置'URL_MODEL' => '0',for example:http://serverName/appName/?m=module&a=action&id=1
模板和操作——————
http://域名/项目名/分组名/模块名/操作名/其他参数
每一个模块就是一个控制器类,通常位于项目的Lib\Action目录下面。
类名就是模块名加上Action后缀;
控制器类必须继承系统的Action基础类,这样才能确保使用Action类内置的方法;
而read操作其实就是IndexAction类的一个公共方法;
如果访问的URL是 http://localhost/App/index.php
在URL里面没有带任何模块和操作的参数,系统就会寻找默认模块DEFAULT_MODULE和默认操作DEFAULT_ACTION,系统默认的默认模块设置是Index模块,默认操作设置是index操作。(在项目配置文件中修改默认模块和默认操作的名称)
定义控制器——————
每个模块是一个Action文件,一个应用如果不需要和数据库交互的时候可以不需要定义模型类,但是必须定义Action控制器,一般位于项目的Lib/Action目录下面。
Action控制器的定义非常简单,只要继承Action基础类就可以了;
for example:Class UserAction extends Action{}
URL生成——————
为了配合所使用的URL模式,ThinkPHP内置提供了U方法;U方法的定义规则如下:
U('[分组/模块/操作]?参数' [,'参数','伪静态后缀','是否跳转','显示域名'])
for example:U('User/add') // 生成User模块的add操作的URL地址
U方法的第二个参数支持数组和字符串两种定义方式:
for example:U('Blog/cate',array('cate_id'=>1,'status'=>1))
'URL_CASE_INSENSITIVE' => true, // 默认false 表示URL区分大小写 true则表示不区分大小写
前置和后置操作——————
前置和后置操作的方法名是在要执行的方法前面加 _before_和_after_,example:
跨膜块调用——————
为了方便跨模块调用,系统内置了A方法和R方法。
A方法表示实例化某个模块,for example: $User = A('User');跨项目调用的格式是:A('[项目名://][分组名/]模块名'),example: A('Admin://User') //表示调用Admin项目的User模块
R方法表示调用一个模块的某个操作方法
页面跳转——————
Success和error方法都有对应的模板
'TMPL_ACTION_ERROR' => APP_PATH.'/Tpl/Home/'.$sys_config['DEFAULT_THEME'].'/public/success.html',
'TMPL_ACTION_SUCCESS' => APP_PATH.'/Tpl/Home/'.$sys_config['DEFAULT_THEME'].'/public/success.html';
模板变量:
$msgTitle 操作标题
$message 页面提示信息
$status 操作状态 1表示成功 0 表示失败 具体还可以由项目本身定义规则
$waitSecond 跳转等待时间 单位为秒
$jumpUrl 跳转页面地址
重定向——————
Action类的redirect方法可以实现页面的重定向功能。
redirect方法的参数用法和U函数的用法一致(参考上面的URL生成部分),例如:$this->redirect('New/category', array('cate_id' => 2), 5, '页面跳转中...');
获取系统变量——————
_get 获取GET参数
_post 获取POST参数
_param 自动判断请求类型获取GET、POST或者PUT参数(3.1新增)
_request 获取REQUEST 参数
_put 获取PUT 参数
_session 获取 $_SESSION 参数
_cookie 获取 $_COOKIE 参数
_server 获取 $_SERVER 参数
_globals 获取 $GLOBALS参数
默认值:(可选)是要获取的参数变量不存在的情况下设置的默认值,example:$this->_get("id","strip_tags",0);如果$_GET["id"] 不存在的话,会返回0。
判断请求类型——————
isGet 判断是否是GET方式提交
isPost 判断是否是POST方式提交
isPut 判断是否是PUT方式提交
isDelete 判断是否是DELETE方式提交
isHead 判断是否是HEAD提交
获取UR参数——————
如果这个值不为空的话,就可以获取URL地址里面的PATH_INFO URL参数:
'VAR_URL_PARAMS' => '_URL_', // PATHINFO URL参数变量
ajax返回——————
'DEFAULT_AJAX_RETURN' => 'JSON', // 默认AJAX 数据返回格式,可选JSON XML ...
ThinkPHP返回的数据格式包括:
status 操作状态
info 提示信息
data 返回数据
for example:$this->ajaxReturn(返回数据,提示信息,操作状态);
Action参数绑定——————
Action参数绑定提供了URL变量和操作方法的参数绑定支持
多层控制器支持——————
for example:A('User','Event');表示实例化Lib/Event/UserEvent.class.php。
——————————模型——————————
模型定义——————
模型类一般位于项目的Lib/Model 目录下面,模型类的命名规则:除去数据表名的前缀,采用驼峰法命名,并且首字母大写,然后加上模型类的后缀定义Model;
for example:
模型名(类名) 约定对应数据表(假设数据库的前缀定义是 think_)
UserModel think_user
模型实例化——————
$User = new Model('User');//实例化User模型
$User = M('User'); //或者使用M()快捷方法实例化,和上面的方法是等效的
$User = new CommonModel('User');//实例化其他公共模型类
字段定义——————
'DB_FIELDS_CACHE' => true, // 启用字段缓存
数据主键——————
$pk = $Model->getPk();//在外部获取当前数据对象的主键名称
属性访问——————
$User = D('User');//实例化User模型
$User->find(1);//查询用户数据
echo $User->name; //获取name属性的值
$User->name = 'ThinkPHP';//设置name属性的值
跨库操作——————
连接数据库——————
在配置文件db_config.php里面填写(如果两种配置参数同时存在的话,DB_DSN配置参数优先。):
<?php
//项目配置文件
return array(
//数据库配置信息
'DB_TYPE' => 'mysql', // 数据库类型
'DB_HOST' => 'localhost', // 服务器地址
'DB_NAME' => 'thinkphp', // 数据库名
'DB_USER' => 'root', // 用户名
'DB_PWD' => '', // 密码
'DB_PORT' => 3306, // 端口
'DB_PREFIX' => 'think_', // 数据库表前缀
//其他项目配置参数
// ...
);
?>
或者采用这种方式配置(数据库类型://用户名:密码@数据库地址:数据库端口/数据库名):
'DB_DSN' => 'mysql://username:password@localhost:3306/DbName'
在模型类定义connection属性
如果在某个模型类里面定义了connection属性的话,则实例化该自定义模型的时候会采用定义的数据库连接信息,而不是配置文件中设置的默认连接信息,通常用于某些数据表位于当前数据库连接之外的其它数据库;
for example:protected $connection = array(...);
protected $connection = 'mysql://root:1234@localhost:3306/thinkphp';//也可以采用DSN方式定义
数据库切换——————
for example:Model->db("数据库编号","数据库配置");
添加了一个编号为1的数据库连接,并自动切换到当前的数据库连接:$this->db(1,"mysql://root:123456@localhost:3306/test")->query("查询SQL");
当第二次切换到相同的数据库的时候,就不需要传入数据库连接信息了,可以直接使用:$this->db(1)->query("查询SQL");
如果需要切换到默认的数据库连接,只需要调用:$this->db(0);
创建数据——————
$User = M('User');// 实例化User模型
$User->create(); // 根据表单提交的POST数据创建数据对象
$User->add(); // 把创建的数据对象写入数据库
字段映射——————
字段映射功能可以让你在表单中隐藏真正的数据表字段,而不用担心放弃自动创建表单对象的功能,比如我们的User表里面有username和email字段,我们需要映射成另外的字段;
for example:
Class UserModel extends Model{
protected $_map = array(
'name' =>'username', // 把表单中name映射到数据表的username字段
'mail' =>'email', // 把表单中的mail映射到数据表的email字段
);
}
如果需要把数据库的数据显示在表单里面,并且也支持字段映射的话,需要对查询的数据进行一下处理,处理方式是调用Model类的parseFieldsMap方法;
for example:
$User = M('User'); // 实例化User模型
$data = $User->find(3);
$data = $User->parseFieldsMap($data);//这样一来,data数据中就包含了name和mail字段数据了,而不再有username和email字段数据了。
连贯操作——————
for example:
这里的where、order和limit方法就被称之为连贯操作方法;
$User->where('status=1')->order('create_time')->limit(10)->select();//查询一个User表的满足状态为1的前10条记录,并希望按照用户的创建时间排序
或者使用参数查询:
$User->select(array('order'=>'create_time','where'=>'status=1','limit'=>'10'));
连贯操作方法还有:
连贯操作 作用 支持的参数类型
where 用于查询或者更新条件的定义 字符串、数组和对象
table 用于定义要操作的数据表名称 字符串和数组
alias 用于给当前数据表定义别名 字符串
data 用于新增或者更新数据之前的数据对象赋值 数组和对象
field 用于定义要查询的字段(支持字段排除) 字符串和数组
order 用于对结果排序 字符串和数组
limit 用于限制查询结果数量 字符串和数字
page 用于查询分页(内部会转换成limit) 字符串和数字
group 用于对查询的group支持 字符串
having 用于对查询的having支持 字符串
join* 用于对查询的join支持 字符串和数组
union* 用于对查询的union支持 字符串、数组和对象
distinct 用于查询的distinct支持 布尔值
lock 用于数据库的锁机制 布尔值
cache 用于查询缓存 支持多个参数
relation 用于关联查询(需要关联模型支持) 字符串
详解:
1》》》where:用于查询或者更新条件的定义。查询或者操作条件,支持字符串、数组和对象,如果不调用where方法,默认不会执行更新和删除操作(Where方法是使用最多的连贯操作方法)。
2》》》table:定义要操作的数据表名称,动态改变当前操作的数据表名称,需要写数据表的全名,包含前缀,可以使用别名和跨库操作。数据表名称,支持操作多个表,支持字符串、数组和对象,如果不调用table方法,会自动获取模型对应或者定义的数据表。
3》》》data:可以用于新增或者保存数据之前的数据对象赋值。如果不调用data方法,则会取当前的数据对象或者传入add和save的数据。如果不定义data方法赋值,也可以使用create方法或者手动给数据对象赋值的方式。
4》》》field(用法:field($field,$except=false)):用于定义要查询的字段。如果不调用field方法,则默认返回所有字段,和field('*')等效。
for example:$Model->field('status',true)->select();//表示获取除了status之外的所有字段。
5》》》order:用于对操作结果排序。如果不调用order方法,按照数据库的默认规则。
6》》》limit:用于定义要查询的结果数量限制(支持所有的数据库类型)
for example:limit("1.10")//如果使用limit('10') 等效于 limit('0,10')
7》》》page:用于定义要查询的数据分页。
for example:
page("2,10");//表示每页显示10条记录的情况下面,获取第2页的数据。
limit(25)->page(3);//表示每页显示25条记录的情况下面,获取第3页的数据。
8》》》group:用于数据库的group查询支持。Group方法的参数只支持字符串。
9》》》having:用于数据库的having查询支持。having方法的参数只支持字符串。
10》》》join:用于数据库的join查询支持。join方法支持多次调用。
11》》》union:用于数据库的union查询支持。Union方法支持多次调用。
12》》》distinct:查询数据的时候进行唯一过滤。
13》》》relation:用于关联查询支持。
14》》》lock: 用于查询或者写入锁定。
15》》》cache(用法:cache($key=true,$expire='',$type='')):key:是否启用查询缓存;expire:查询缓存的有效期;type:查询缓存的缓存类型;
CURD操作——————(创建、更新、读取和删除的实现是最基本的)
创建(create):
add(用法:add($data='',$options=array(),$replace=false)):写入(新增)数据到数据库。data:要新增的数据;option:操作表达式;replace:是否允许写入时更新;
for example:
$User = M("User"); // 实例化User对象
$data['name'] = 'ThinkPHP';
$data['email'] = 'ThinkPHP@gmail.com';
$User->add($data);
或者使用data连贯方法:
$User->data($data)->add();
如果在add之前已经创建数据对象的话(例如使用了create或者data方法),add方法就不需要再传入数据了。
for example:
$User = M("User"); // 实例化User对象
$User->create();// 根据表单提交的POST数据创建数据对象
$User->add(); // 根据条件保存修改的数据
addAll:批量插入数据的addAll(仅针对Mysql数据库)。
for example:$User->addAll($data)
读取(Read):
selcet:查询数据集。通常配合连贯操作where、field、order、limit、join等一起使用。Select方法配合连贯操作方法可以完成复杂的数据查询。
for example:
$User = M("User"); // 实例化User对象
$list = $User->where('status=1')->order('create_time')->limit(10)->select();// 查找status值为1的用户数据 以创建时间排序 返回10条数据
find:查询数据。读取数据的操作其实和数据集的类似,select可用的所有连贯操作方法也都可以用于find方法,区别在于find方法最多只会返回一条记录,因此limit方法对于find查询操作是无效的。
for example:
即使满足条件的数据不止一条,find方法也只会返回第一条记录。
$User = M("User"); // 实例化User对象
$User->where('status=1 AND name="think"')->find(); // 查找status值为1name值为think的用户数据;
getField(用法:getField($field,$sepa=null)):查询某个字段的值。通常配合连贯操作where、limit、order等一起使用。
for example:
当只有一个字段的时候,默认返回一个值。
$User = M("User"); // 实例化User对象
$nickname = $User->where('id=3')->getField('nickname');// 获取ID为3的用户的昵称
如果是返回数组则:
$this->getField('id',true); // 获取id数组
getField方法的sepa参数还可以支持限制数量,for example:还可以配合使用order方法使用。
$this->getField('id,name',5); // 限制返回5条记录
$this->getField('id',3); // 获取id数组 限制3条记录
更新(Update):
save(用法:save($data='',$options=array())):更新数据到数据库。data:要保存的数据,如果为空,则取当前的数据对象;option:为数组的时候表示操作表达式,通常由连贯操作完成;通常配合连贯操作where、field、order等一起使用。
for example:
$User = M("User"); // 实例化User对象
$data['name'] = 'ThinkPHP';// 要修改的数据对象属性赋值
$data['email'] = 'ThinkPHP@gmail.com';
$User->where('id=5')->save($data); // 根据条件保存修改的数据
setField:更新某个字段的值。必须配合连贯操作where一起使用。
for example:
$User = M("User"); // 实例化User对象
$User-> where('id=5')->setField('name','ThinkPHP');// 更改用户的name值
更新多个字段:
$data = array('name'=>'ThinkPHP','email'=>'ThinkPHP@gmail.com');// 更改用户的name和email的值
$User-> where('id=5')->setField($data);
setInc和setDec:字段增长/字段减少。setInc($field,$step=1)字段值增长;setDec($field,$step=1)字段值减少;
for example:
$User = M("User"); // 实例化User对象
$User->where('id=5')->setInc('score',3); // 用户的积分加3
$User->where('id=5')->setDec('score'); // 用户的积分减1
删除(Delete):
delete:删除数据库中的记录。
for example:
$User = M("User"); // 实例化User对象
$User->where('id=5')->delete(); // 删除id为5的用户数据
$User->where('status=0')->delete(); // 删除所有状态为0的用户数据
也可以用order和limit方法来限制要删除的个数,for example:
$User->where('status=0')->order('create_time')->limit('5')->delete(); // 删除所有状态为0的5个用户数据按照创建时间排序
自动验证——————
需要使用系统的自动验证功能,只需要在Model类里面定义$_validate属性,是由多个验证因子组成的二维数组。
验证因子格式:array(验证字段,验证规则,错误提示,[验证条件,附加规则,验证时间])
自动完成——————
在Model类定义 $_auto 属性,$_auto属性是由多个填充因子组成的数组。
填充因子格式:array(填充字段,填充内容,[填充条件,附加规则])
查询语言——————
ThinkPHP可以支持直接使用字符串作为查询条件,但是大多数情况推荐使用索引数组或者对象来作为查询条件,因为会更加安全。
查询方式:
使用字符串作为查询条件》》》
for example:
$User = M("User"); // 实例化User对象
$User->where('type=1 AND status=1')->select();
最后生成的SQL语句是
SELECT * FROM think_user WHERE type=1 AND status=1
使用数组作为查询条件》》》
$User = M("User"); // 实例化User对象
$condition['name'] = 'thinkphp';
$condition['status'] = 1;
$User->where($condition)->select(); // 把查询条件传入查询方法
最后生成的SQL语句是
SELECT * FROM think_user WHERE `name`='thinkphp' AND status=1
使用对象对象老查询(这里以stdClass内置对象为例):
$User = M("User"); // 实例化User对象
// 定义查询条件
$condition = new stdClass();
$condition->name = 'thinkphp';
$condition->status= 1;
$User->where($condition)->select();
最后生成的SQL语句和上面一样
SELECT * FROM think_user WHERE `name`='thinkphp' AND status=1
表达式查询:
表达式 含义
EQ 等于(=)
NEQ 不等于(<>)
GT 大于(>)
EGT 大于等于(>=)
LT 小于(<)
ELT 小于等于(<=)
LIKE 模糊查询
[NOT] BETWEEN (不在)区间查询
[NOT] IN (不在)IN 查询
EXP 表达式查询,支持SQL语法
for example:
$map['id']=array('eq',100)和下面的查询等效$map['id']=100;
配置了DB_LIKE_FIELDS参数的话,某些字段也会自动进行模糊查询,for example:
'DB_LIKE_FIELDS'=>'title|content'
快捷查询(注意:快捷查询方式中“|”和“&”不能同时使用。):
实现不同字段相同的查询条件》》》
$User = M("User"); // 实例化User对象
$map['name|title'] = 'thinkphp';
$User->where($map)->select(); // 把查询条件传入查询方法
查询条件就变成 name= 'thinkphp' OR title = 'thinkphp'
实现不同字段不同的查询条件》》》
$User = M("User"); // 实例化User对象
$map['status&title'] =array('1','thinkphp','_multi'=>true);
$User->where($map)->select();// 把查询条件传入查询方法
'_multi'=>true必须加在数组的最后,表示当前是多条件匹配,这样查询条件就变成 status= 1 AND title = 'thinkphp' ,查询字段支持更多的
区间查询:
for example:
$map['id'] = array(array('gt',1),array('lt',10)) ;//得到的查询条件是: (`id` > 1) AND (`id` < 10)
组合查询:
字符串模式查询(采用_string 作为查询条件,数组条件还可以和字符串条件混合使用。)》》》
for example:
$User = M("User"); // 实例化User对象
$map['id'] = array('neq',1);
$map['name'] = 'ok';
$map['_string'] = 'status=1 AND score>10';
$User->where($map)->select();
最后得到的查询条件就成了:
( `id` != 1 ) AND ( `name` = 'ok' ) AND ( status=1 AND score>10 )
请求字符串查询方式(采用_query 作为查询条件,请求字符串查询是一种类似于URL传参的方式,可以支持简单的条件相等判断。)》》》
for example:
$map['id'] = array('gt','100');
$map['_query'] = 'status=1&score=100&_logic=or';
得到的查询条件是:`id`>100 AND (`status` = '1' OR `score` = '100')
复合查询(采用_complex作为查询条件,复合查询相当于封装了一个新的查询条件,然后并入原来的查询条件之中,所以可以完成比较复杂的查询条件组装。):
for example:
$where['name'] = array('like', '%thinkphp%');
$where['title'] = array('like','%thinkphp%');
$where['_logic'] = 'or';
$map['_complex'] = $where;
$map['id'] = array('gt',1);
查询条件是
( id > 1) AND ( ( name like '%thinkphp%') OR ( title like '%thinkphp%') )
上面的查询方法还可以改写成:
$where['id'] = array('gt',1);
$where['_string'] = ' (name like "%thinkphp%") OR ( title like "%thinkphp") ';
统计查询(ThinkPHP为这些统计操作提供了一系列的内置方法),如下:
方法 说明
Count 统计数量,参数是要统计的字段名(可选)
Max 获取最大值,参数是要统计的字段名(必须)
Min 获取最小值,参数是要统计的字段名(必须)
Avg 获取平均值,参数是要统计的字段名(必须)
Sum 获取总分,参数是要统计的字段名(必须)
定位查询(ThinkPHP支持定位查询,但是要求当前模型必须继承高级模型类才能使用,可以使用getN方法直接返回查询结果中的某个位置的记录):
for example:
$User->where('score>0')->order('score desc')->getN(2);//获取符合条件的第3条记录
$User->where('score>80')->order('score desc')->first();//获取第一条记录
$User->where('score>80')->order('score desc')->last();//获取最后一条记录
SQL查询:
query方法(用法:query($sql,$parse=false)):执行SQL查询操作。
for example:
$Model = new Model() // 实例化一个model对象 没有对应任何数据表
$Model->query("select * from think_user where status=1");
如果你当前采用了分布式数据库,并且设置了读写分离的话,query方法始终是在读服务器执行,因此query方法对应的都是读操作
execute方法(用法:execute($sql,$parse=false)):用于更新和写入数据的sql操作。
for example:
$Model = new Model() // 实例化一个model对象 没有对应任何数据表
$Model->execute("update think_user set name='thinkPHP' where status=1");
如果你当前采用了分布式数据库,并且设置了读写分离的话,execute方法始终是在读服务器执行,因此query方法对应的都是读操作
其他技巧:
自动获取当前表名》》》
for example:
$model = M("User");
$model->query('select * from __TABLE__ where status>1');//使用了__TABLE__ 这样一个字符串,系统在解析的时候会自动替换成当前模型对应的表名,这样就可以做到即使模型对应的表名变化,y也不用修改原生的sql语句。
替换字符串 对应连贯操作方法
%FIELD% field
%TABLE% table
%DISTINCT% distinct
%WHERE% where
%JOIN% join
%GROUP% group
%HAVING% having
%ORDER% order
%LIMIT% limit
%UNION% union
动态查询:
方法名 说明 举例
getBy 根据某个字段的值查询数据 例如,getByName,getByEmail
getFieldBy 根据某个字段查询并返回某个字段的值 例如,getFieldByName
top 获取前多少条记录(需要高级模型支持) 例如,top8,top12
getBy动态查询》》》该查询方式针对数据表的字段进行查询
for example:
$user = $User->getByName('liu21st');
getFieldBy动态查询》》》针对某个字段查询并返回某个字段的值
for example:
$user = $User->getFieldByName('liu21st','id');//表示根据用户的name获取用户的id值
top动态查询》》》
for example:
$User-> where('score>80')->order('score desc')->top5();//我们需要获取当前用户中积分大于0,积分最高的前5位用户
子查询:
使用select方法:当select方法的参数为false的时候,表示不进行查询只是返回构建SQL;
for example:$subQuery = $model->field('id,name')->table('tablename')->group('field')->where($where)->order('status')->select(false); // 首先构造子查询SQL
使用buildSql方法:$subQuery = $model->field('id,name')->table('tablename')->group('field')->where($where)->order('status')->buildSql(); // 调用buildSql方法后不会进行实际的查询操作,而只是生成该次查询的SQL语句(为了避免混淆,会在SQL两边加上括号),然后我们直接在后续的查询中直接调用。
$model->table($subQuery.' a')->where()->order()->select()// 利用子查询进行查询
查询锁定:只需要在查询或者更新之前使用lock方法即可。
查询锁定使用:
$list = $User->lock(true)->where('status=1')->order('create_time')->limit(10)->select();
更新锁定使用:
$list = $User->lock(true)->where('status=1')->data($data)->save();
字段排除——————
——————————视图——————————
模板定义————————
默认的模板文件定义规则是:模板目录/[分组名/][模板主题/]模块名/操作名+模板后缀
模板赋值————————
要在模板中输出变量,必须在在Action类中把变量传递给模板,视图类提供了assign方法对模板变量赋值,无论何种变量类型都统一使用assign赋值。
for example:
$this->assign('name',$value);
// 下面的写法是等效的
$this->name = $value;
如果要同时输出多个模板变量,可以使用下面的方式:
$array['name'] = 'thinkphp';
$array['email'] = 'liu21st@gmail.com';
$array['phone'] = '12335678';
$this->assign($array);
模板输出——————
模板变量赋值后就需要调用模板文件来输出相关的变量,模板调用通过display方法来实现。我们在操作方法的最后使用:
$this->display();
调用当前模块的其他操作模板》》》
格式:display('操作名')
for example:$this->display('edit');
调用其他模块的操作模板》》》
格式:display('模块名:操作名')
for example:$this->display('Member:read'); //当前是User模块,我们需要调用Member模块的read操作模版
调用其他主题的操作模板》》》
格式:display('主题名:模块名:操作名')
for example:$this->display('Xp:User:edit'); //调用Xp主题的User模块的edit操作模版
直接全路径输出模板》》》
格式:display('模板文件名')
for example:$this->display('./Public/menu.html');//输出当前的Public目录下面的menu.html模板文件
直接解析内容》》》
for example:
Action类的display方法如果传入第四个参数,表示不读取模板文件而是直接解析内容
$this->assign('foo','ThinkPHP');
$this->show('Hello, {$foo}!'); //会在页面输出: Hello,ThinkPHP!
show方法也可以支持指定编码和输出格式
for example:
$this->show($content, 'utf-8', 'text/xml');
模板替换——————
获取内容——————
有些时候我们不想直接输出模板内容,而是希望对内容再进行一些处理后输出,就可以使用fetch方法来获取解析后的模板内容,在Action类里面使用:
$content = $this->fetch();
$content = $this->fetch('Member:read'); //fetch的参数用法和Display方法基本一致
模板引擎——————
变量输出》》》
for example:
如果我们在Action中赋值了一个name模板变量:
$name = 'ThinkPHP';
$this->assign('name',$name);
使用内置的模板引擎输出变量,只需要在模版文件使用:{$name}
模板编译后的结果就是:<?php echo($name);?>
assign方法里面的第一个参数才是模板文件中使用的变量名称。如果改成下面的代码:
name = 'ThinkPHP';
$this->assign('name2',$name);
再使用{$name} 输出就无效了,必须使用 {$name2}才能输出模板变量的值了。
——————————————————————————————————————————————————————
注意:模板标签的{和$之间不能有任何的空格,否则标签无效
3.1版本以后,类的属性输出方式有所调整,支持原生的php的写法: {$user->name}// 输出用户的名称
'TMPL_VAR_IDENTIFY' => 'array', // 模板变量识别。留空自动判断,参数为'obj'则表示对象
系统变量》》》
用法 含义 例子
$Think.server 获取$_SERVER {$Think.server.php_self}
$Think.get 获取$_GET {$Think.get.id}
$Think.post 获取$_POST {$Think.post.name}
$Think.request 获取$_REQUEST {$Think.request.user_id}
$Think.cookie 获取$_COOKIE {$Think.cookie.username}
$Think.session 获取$_SESSION {$Think.session.user_id}
$Think.config 获取系统配置参数 {$Think.config.app_status}
$Think.lang 获取系统语言变量 {$Think.lang.user_type}
$Think.const 获取系统常量 {$Think.const.app_name}或{$Think.APP_NAME}
$Think.env 获取环境变量 {$Think.env.HOSTNAME}
$Think.version 获取框架版本号 {$Think.version}
$Think.now 获取当前时间 {$Think.now}
$Think.template 获取当前模板 {$Think.template}
$Think.ldelim 获取模板左界定符 {$Think.ldelim}
$Think.rdelim 获取模板右界定符 {$Think.rdelim}
特殊变量》》》由ThinkPHP系统内部定义的常量
{$Think.version} //版本
{$Think.now} //现在时间
{$Think.template|basename} //模板页面
{$Think.LDELIM} //模板标签起始符号
{$Think.RDELIM} //模板标签结束符号
使用函数————————
模板变量的函数调用格式为:{$varname|function1|function2=arg1,arg2,### }
执行函数并输出返回值:格式:{:function(…)}
for example:
{:U('User/insert')}//输出U函数的返回值
编译后的PHP代码是:
<?php echo U('User/insert');?>
执行函数但不输出:格式:{~function(…)}
for example:
{~say_hello('ThinkPHP')}//调用say_hello函数
编译后的PHP代码是:
<?php say_hello('ThinkPHP');?>
默认值输出————————
格式:{$变量|default="默认值"}
使用运算符————————
运算符 使用示例
+ {$a+$b}
- {$a-$b}
* {$a*$b}
/ {$a/$b}
% {$a%$b}
++ {$a++} 或 {++$a}
-- {$a--} 或 {--$a}
综合运算:{$a+$b*10+$c}
for example:
{$user.score+10} 是错误的
{$user['score']+10} 是正确的
{$user['score']|myFun*10} 错误的
{$user['score']+myFun($user['level'])} 正确的
内置标签———————
标签名 作用 包含属性
include 包含外部模板文件(闭合) ile
import 导入资源文件(闭合 包括js css load别名) ile,href,type,value,basepath
volist 循环数组数据输出 me,id,offset,length,key,mod
foreach 数组或对象遍历输出 me,item,key
for For循环数据输出 me,from,to,before,step
switch 分支判断输出 name
case 分支判断输出(必须和switch配套使用) value,break
default 默认情况输出(闭合 必须和switch配套使用) 无
compare 比较输出(包括eq neq lt gt egt elt heq nheq等别名) name,value,type
range 范围判断输出(包括in notin between notbetween别名) name,value,type
present 判断是否赋值 name
notpresent 判断是否尚未赋值 name
empty 判断数据是否为空 name
notempty 判断数据是否不为空 name
defined 判断常量是否定义 name
notdefined 判断常量是否未定义 name
define 常量定义(闭合) name,value
assign 变量赋值(闭合) name,value
if 条件判断输出 condition
elseif 条件判断输出(闭合 必须和if标签配套使用) condition
else 条件不成立输出(闭合 可用于其他标签) 无
php 使用php代码 无
包含文件——————
使用完整文件名包含》》》
格式:<include file="完整模板文件名" />
包含当前模块的其他操作模板文件》》》
格式:<include file="操作名" />
包含其他模块的操作模板》》》
格式:<include file="模块名:操作名" />
包含其他模板主题的模块操作模板》》》
格式:<include file="主题名:模块名:操作名" />
用变量控制要导入的模版》》》
格式:<include file="$变量名" />
Include标签支持在包含文件的同时传入参数。
for example:<include file="header" title="ThinkPHP框架"keywords="开源WEB开发框架"/>
就可以在包含的header.html文件里面使用var1和var2变量了:<meta name="keywords" content="[keywords]" />
导入文件——————
传统方式(导入js和css):
<script type='text/javascript' src='/Public/Js/Util/Array.js'>
<link rel="stylesheet" type="text/css" href="/App/Tpl/default/Public/css/style.css" />
简化导入:
第一个标签import——————
《《js》》
<import type='js' file="Js.Until.Array" />
Type属性默认是js,所以下面的效果是相同的:
<import file="Js.Util.Array" />
多个文件批量导入(中间加逗号):<import file="Js.Util.Array,Js.Util.Date" />
《《css》》
<import type='css' file="Css.common" />//导入外部CSS文件必须指定type属性的值
导入默认方式的是public,如果需要指定其他的目录,可以使用basepath属性:<import file="Js.Util.Array" basepath="./Common" />
第二个标签load——————
for example:
Load标签可以无需指定type属性,系统会自动根据后缀自动判断。
<load href="/Book/Tpl/Home/Public/Js/Common.js" />
<load href="/Book/Tpl/Home/Public/Css/common.css" />
系统还提供了两个标签别名js和css 用法和load一致,例如:
<js href="/Public/Js/Common.js" />
<css href="/Book/Tpl/Home/Public/Css/common.css" />
Volist标签——————
主要用于在模板中循环输出数据集或者多维数组。
for example:
$User = M('User');
$list = $User->select();
$this->assign('list',$list);//在Action中首先对模版赋值
然后在模板里面,循环输出用户的编号和姓名:
<volist name="list" id="vo">//name属性表示模板赋值的变量名称,id表示当前的循环变量,可以随意指定(不要和name属性冲突)。
{$vo.id}
{$vo.name}
</volist>
如果想输出部分数据:
<volist name="list" id="vo" offset="5" length="10"></volist> //输出其中的第5~15条记录
如果想输出偶数记录:
<volist name="list" id="vo" mod="2" >
Mod属性还用于控制一定记录的换行:
<volist name="list" id="vo" mod="5" >
{$vo.name}
<eq name="mod" value="4"><br/></eq>
</volist>
为空的提示:
<volist name="list" id="vo" empty="暂时没有数据" >
{$vo.id}|{$vo.name}
</volist>
输出循环变量:
<volist name="list" id="vo" key="k" >//如果没有指定key,则默认使用循环变量i
如果要输出数组的索引,可以直接使用key变量:
<volist name="list" id="vo" >
{$key}.{$vo.name}
</volist>
foreach标签——————
用于循环输出,Foreach标签相对比volist标签简洁,没有volist标签那么多的功能。优势是可以对对象进行遍历输出,而volist标签通常是用于输出数组。
for example:
<foreach name="list" item="vo">
{$vo.id}
{$vo.name}
</foreach>
for标签——————
for example:
<for start="开始值" end="结束值" comparison="" step="步进值" name="循环变量名" ></for>
switch标签——————
for example:
<switch name="变量" >
<case value="值1" break="0或1">输出内容1</case>
<case value="值2">输出内容2</case>
<default />默认情况
</switch>
比较标签——————
eq或者 equal 等于
neq 或者notequal 不等于
gt 大于
egt 大于等于
lt 小于
elt 小于等于
heq 恒等于
nheq 不恒等于
for example:
<eq name="name" value="value">value</eq>//要求name变量的值等于value就输出
<gt name="name" value="5">value</gt>//当 name变量的值大于5就输出
判断标签——————
in标签》》》判断模板变量是否在某个范围内
<in name="id"value="1,2,3">输出内容1</in>
notin标签》》》判断不再某个范围内
<notin name="id"value="1,2,3">输出内容2</notin>
把上面两个标签合并成为:
<in name="id"value="1,2,3">输出内容1<else/>输出内容2</in>
between标签》》》来判断变量是否在某个区间范围内(notbetween标签相反)区间范围只支持两个值
<between name="id"value="1,10">输出内容1</between>
也可以直接使用range标签,替换in和notin的用法:
<range name="id"value="1,2,3"type="in">输出内容1</range>
present标签——————
判断模板变量是否已经赋值
for example:
<present name="name">name已经赋值</present>
<notpresent name="name">name还没有赋值</notpresent>
<present name="name">name已经赋值<else /> name还没有赋值</present>//把上面两个标签合并
empty标签——————
判断模板变量是否为空
<empty name="name">name为空值</empty>
defined标签——————
判断常量是否已经有定义
<defined name="NAME">NAME常量已经定义</defined>
defined标签——————
进行常量定义
<define name="MY_DEFINE_NAME"value="3"/>//在运行模板的时候 定义了一个MY_DEFINE_NAME的常量
assgin标签——————
进行赋值
<assign name="var" value="123" />//运行模板的时候 赋值了一个var的变量,值是123
if标签——————
进行条件判断
for example:
<if condition="($name eq 1) OR ($name gt 100) "> value1
<elseif condition="$name eq 2"/>value2
<else /> value3
</if>
在condition属性中可以支持eq等判断表达式:
<if condition="$id lt 5 ">value1
<else /> value2
</if>
标签嵌套——————
'TAG_NESTED_LEVEL' =>3//默认的嵌套层次是3级
使用php代码——————
'TMPL_DENY_PHP' => false, // 默认模板引擎是否禁用PHP原生代码
模板继承———————
使用block标签
模板布局——————
该方式需要配置开启LAYOUT_ON 参数(默认不开启),并且设置布局入口文件名LAYOUT_NAME(默认为layout)。
如果开启,我们的模板渲染流程就有所变化:
for example:
Class UserAction extends Action {
Public function add() {
$this->display('add');
}
}
在不开启LAYOUT_ON布局模板之前,会直接渲染Tpl/User/add.html 模板文件,开启之后,首先会渲染Tpl/layout.html 模板;
下面是一个典型的layout.html模板的写法:{__CONTENT__}//读取layout模板之后,会再解析User/add.html 模板文件,并把解析后的内容替换到layout布局模板文件的{__CONTENT__} 特定字符串。
原样输出———————
literal标签(保持原样输出)
引入标签库——————
导入标签库使用tagLib标签
修改定界符——————
避免js混淆——————
总共有三个方法:
第一种:{$('name').value}改成{ $('name').value}//因为内置模板引擎的解析规则是"{"后面紧跟"$"符号才会解析变量 因此只要在"{" 和"$"之间添加空格就不会被误解析了
第二种:使用内置的literal标签包含js代码
第三种:定制模板引擎标签的定界符:'TMPL_L_DELIM'=>'<{','TMPL_R_DELIM'=>'}>'
日志级别——————
ThinkPHP对系统的日志按照级别来分类,包括:
EMERG 严重错误,导致系统崩溃无法使用
ALERT 警戒性错误, 必须被立即修改的错误
CRIT 临界值错误, 超过临界值的错误
ERR 一般性错误
WARN 警告性错误, 需要发出警告的错误
NOTICE 通知,程序可以运行但是还不够完美的错误
INFO 信息,程序输出信息
DEBUG 调试,用于调试信息
SQL SQL语句,该级别只在调试模式开启时有效
'LOG_RECORD' => false, // 进行日志记录
——————————调试——————————
调试方法——————
变量调试》》》
除了使用php内置的var_dump和print_r之外,ThinkPHP框架内置了一个对浏览器友好的var_dump方法;
性能调试》》》
系统提供了一些方法可以很方便的获取某个区间的运行时间和内存占用情况:
debug_start 区间调试开始(记录初始时间和内存占用);
debug_end 区间调试结束(记录区间结束时间和内存占用 并输出结果);
如果只是需要调试时间开销,可以使用C函数来实现更方便实现:
G 用于记录和统计时间(微秒)
动态缓存——————
所有的缓存方式都被统一使用公共的调用接口,这个接口就是Cache缓存类。
缓存类的使用:
$Cache = Cache::getInstance('缓存方式','缓存参数'),
缓存目录:temp(默认由DATA_CACHE_PATH参数配置)
快捷缓存——————
使用S方法;
sql解析缓存——————
开启SQL解析缓存,只需要设置:'DB_SQL_BUILD_CACHE' => true,
设置缓存长度:'DB_SQL_BUILD_LENGTH' => 20, // SQL缓存的队列长度
静态缓存——————
使用静态缓存功能,需要开启HTML_CACHE_ON参数,并且使用HTML_CACHE_RULES配置参数设置静态缓存规则文件 。
和静态缓存相关的配置参数包括:
HTML_CACHE_ON 是否开启静态缓存功能
HTML_FILE_SUFFIX 静态文件后缀 惯例配置的值是 .html
HTML_CACHE_TIME 默认的静态缓存有效期 默认60秒 可以在静态规则定义覆盖
——————————扩展——————————
模式扩展———————
简洁模式》》》
define('MODE_NAME','Thin'); // 采用简洁模式运行
精简模式》》》
define('MODE_NAME','Lite'); // 采用精简模式运行
命令模式》》》
define('MODE_NAME', 'cli'); // 采用CLI运行模式运行
AMF模式》》》
define('MODE_NAME', 'amf'); // 采用Amf运行模式运行
PHPRPC模式》》》
define('MODE_NAME', 'phprpc'); // 采用Phprpc运行模式运行
REST模式》》》
define('MODE_NAME', 'rest'); // 采用rest模式运行
定制模式扩展》》》
core 系统核心列表文件定义
config 模式配置文件
alias 模式别名定义文件
extends 模式系统行为定义
tags 应用行为定义文件
——————————安全——————————
表单令牌———————
表单令牌验证功能,可以有效防止表单的重复提交等安全防护。
'TOKEN_ON'=>true, // 是否开启令牌验证
字段类型验证———————
'DB_FIELDTYPE_CHECK'=>true, // 开启字段类型验证
目录安全文件———————
保护模板文件———————
———————————部署——————————
隐藏index.php——————
——————————杂项————————————
session支持——————(cookie数据保存在客户端,session数据保存在服务器端)
用于Session 设置、获取、删除和管理操作
session初始化设置》》》
如果session方法的name参数传入数组则表示进行session初始化设置,例如:
session(array('name'=>'session_id','expire'=>3600));
支持传入的session参数包括:
参数名 说明
id session_id值
name session_name 值
path session_save_path 值
prefix session 本地化空间前缀
expire session.gc_maxlifetime 设置值
domain session.cookie_domain 设置值
use_cookies session.use_cookies 设置值
use_trans_sid session.use_trans_sid 设置值
type session hander类型,可以使用hander驱动扩展
session赋值》》》
session('name','value'); //设置session
session取值》》》
$value = session('name');
session删除》》》
session('name',null); // 删除name
session(null);//清空当前的session
session判断》》》
session('?name')//判断名称为name的session值是否已经设置
session管理》》》
session('[操作名]');
支持的操作名包括:
操作名 含义
start 启动session
pause 暂停session写入
destroy 销毁session
regenerate 重新生成session id
本地化支持——————
本地化session支持开启后,生成的session数据格式由原来的:$_SESSION['name'] 变成 $_SESSION['前缀'] ['name']
cookie支持——————
用于Cookie 设置、获取、删除操作
cookie设置》》》
cookie('name','value','3600');//设置cookie,指定cookie保存时间;
cookie获取》》》
$value = cookie('name');
cookie删除》》》
cookie('name',null);//删除name的cookie值;
cookie(null);//删除所有cookie值;
cookie(null,'think_');//清空指定前缀的所有cookie值;
多语言——————
启动多语言,在配置目录下面的行为定义文件tags.php中,添加:
return array(
'app_begin'=>array('CheckLang')//表示在app_begin标签位置执行多语言检测行为
);
开启语言包功能:
'LANG_SWITCH_ON' => true, // 开启语言包功能
其他的配置参数:
'LANG_AUTO_DETECT' => true, // 自动侦测语言 开启多语言功能后有效
'LANG_LIST' => 'zh-cn', // 允许切换的语言列表 用逗号分隔
'VAR_LANGUAGE' => 'l', // 默认语言切换变量
项目语言包文件》》》lang目录下面
语言包命名规范》》》
项目公共语言包:语言目录/common.php
项目分组语言包:语言目录/分组名.php
项目模块语言包:不存在分组情况:语言目录/模块名(小写).php
存在分组的情况:语言目录/分组名/模块名(小写).php
语言包也可以按照模板来定义,每个模板单独定义语言文件》》》
Lang/zh-cn/user.php 表示给User模块定义简体中文语言包文件
如果项目比较小,只有一个语言包文件,那么可以定义common.php文件;
'TMPL_FILE_DEPR'=>'_',//语言目录/分组名_模块名(小写).php
在程序里面设置语言定义的值,使用小面的方式:
L('define2','语言定义');
$value = L('define2');
数据分页——————
两种方法:
第一种:利用page类和limit方法
$User = M('User'); // 实例化User对象
import('ORG.Util.Page');// 导入分页类
$count = $User->where('status=1')->count();// 查询满足要求的总记录数
$Page = new Page($count,25);// 实例化分页类 传入总记录数和每页显示的记录数
$show = $Page->show();// 分页显示输出
// 进行分页数据查询 注意limit方法的参数要使用Page类的属性
$list = $User->where('status=1')->order('create_time')->limit($Page->firstRow.','.$Page->listRows)->select();
$this->assign('list',$list);// 赋值数据集
$this->assign('page',$show);// 赋值分页输出
$this->display(); // 输出模板
第二种:分页类和page方法的实现
$User = M('User'); // 实例化User对象
// 进行分页数据查询 注意page方法的参数的前面部分是当前的页数使用 $_GET[p]获取
$list = $User->where('status=1')->order('create_time')->page($_GET['p'].',25')->select();
$this->assign('list',$list);// 赋值数据集
import(“ORG.Util.Page”);// 导入分页类
$count = $User->where('status=1')->count();// 查询满足要求的总记录数
$Page = new Page($count,25);// 实例化分页类 传入总记录数和每页显示的记录数
$show = $Page->show();// 分页显示输出
$this->assign('page',$show);// 赋值分页输出
$this->display(); // 输出模板
分页样式定制:
分页类page提供了一个setConfig方法来修改的一些设置:
header:头部描述信息,默认值 “条记录”
prev: 上一页描述信息,默认值是“上一页”
next: 下一页描述信息,默认值是“下一页”
first: 第一页描述信息,默认值是“第一页”
last: 最后一页描述信息,默认值是“最后一页”
文件上传——————
上传类使用ORG.Net.UploadFile类
验证码——————
使用扩展类中的ORG.Util.String类和ORG.Util.String类库,通过在在模块类中增加一个verify方法来用于显示验证码:
Image类的buildImageVerify方法用于生成验证码;
图片添加水印——————
可以通过使用Image类的水印方法给图片添加水印支持,例如:
import('ORG.Util.Image');
$Image = new Image();
// 给avator.jpg 图片添加logo水印
$Image->water('/avator.jpg','/logo.jpg');
ip获取和定位——————
系统内置了get_client_ip方法用于获取客户端的IP地址,使用示例:
$ip = get_client_ip();
如果要支持IP定位功能,需要使用扩展类库ORG.Net.IpLocation,并且要配合IP地址库文件一起使用,例如:
import('ORG.Net.IpLocation');// 导入IpLocation类
$Ip = new IpLocation('UTFWry.dat'); // 实例化类 参数表示IP地址库文件
$area = $Ip->getlocation('203.34.5.66'); // 获取某个IP地址所在的位置
常量参考——————http://www.edbiji.com/doccenter/showdoc/43/nav/672.html
配置参考——————http://www.edbiji.com/doccenter/showdoc/43/nav/673.html
————————————————
版权声明:本文为CSDN博主「dae bal」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/baidu_39043816/article/details/109311653