ThinkPHP框架php
1、框架介绍css
PHP框架真正的发展是从php5开始的,在php5中对对象模型的修改对框架的发展起了很大的做用。PHP框架就是经过提供一个开发web程序的基本架构,把基于web开发的PHP程序摆到流水线上。换句话说,php开发框架有助于促进快速软件开发,节约了开发时间,减小了代码的重复编写。html
1.一、什么是框架前端
框架(framework)其实就是开发一个系统的半成品,是在一个给定的问题领域内,实现一个应用程序的一部分设计,简单的说就是项目骨架已经搭好并提供了丰富的组建库,只增长了一些内容或者调用一些提供好的组件就能够完成本身的系统。mysql
咱们能够把框架的项目部署理解为一个建筑的地基以及环境的搭建,组建库理解为各类建筑材料,咱们只须要“装修”一番,就能够将其变成办公楼,住宅楼,商业街....(我的主页、OA系统、电子商城....)程序员
1.二、为何要用框架web
框架最大的好处就是重用。由于web发展到今天已经很复杂了,特别是服务器软件,涉及到的知识、内容和问题已经不少了,在项目开发过程当中若是若是使用一个成熟的框架,就至关于让别人帮你完成了一些基础工做(50%以上),咱们只须要集中精力完成系统的业务逻辑设计。并且框架通常都是成熟稳健的,能够处理系统的不少细节问题,好比事物处理,安全性,数据流控制等问题。还有框架通常都通过不少人使用,因此结构、扩展都很好,并且是不断升级的,你能够直接享受别人升级代码带来的好处。框架也将问题划分开了各个解决,易于控制,易于延展,易于分配资源。应用框架强调的是软件的设计重用性和系统的可扩展性,以缩短大型软件应用系统的开发周期,提升开发质量。ajax
1.三、框架和MVCsql
框架是软件,而设计模式是软件的知识,一个框架每每含有一个或者多个设计模式,如今几乎全部流行的PHP框架都能实现MVC设计模式,将开发程序强制拆分红视图、控制器和模型三层,因此,使用框架后,就不用纠结去如何实现MVC了。若是不用框架去实现MVC,不只MVC不易于理解,分离的难度也比较高。thinkphp
M - Model 模型 负责数据操做
V - View 视图、模版 负责前台页面显示
C - Controller 模块 描述功能,调度M和V
一个框架不只要具有MVC。还要具有如下一些功能
1.3.一、目录组织结构
能够自动部署项目所需的所有目录结构,或按框架的规则要求,建立项目的目录结构
1.3.二、类加载
框架中全部开发中用到的功能类,均可以自动加载。包括系统中提供的强大的基类库,以及用户自定义的功能类
1.3.三、基础类
每一个成熟的框架都为用户提供了很是丰富的基类,让程序员在自定义方法中直接就能够从基类中继承来大量的功能
1.3.四、URL处理
框架中几乎都须要URL处理方式。对URL的管理包括两个方面。首先当用户请求约定的URL时,应用程序须要解析它变成能够理解的参数。第二,应用程序须要提供一种创造URL的方法,以便建立的URL应用程序是能够理解的。
1.3.五、输入处理
用户的一些输入一般都在URL参数中,或者经过表单提交。为了防止一些不合理的数据和输入攻击,框架中能够完成对输入内容进行过滤以及自动完成一些数据验证工做。
1.3.六、错误异常处理
在使用框架开发系统时,框架会提供一些配套的错误处理方式和程序调试模式,方便程序员快速解决开发中遇到的问题
1.3.七、扩展类
在框架中除了提供一些丰富的基类,还会提供一些经常使用的功能扩展类,包括web项目中一些常见功能,像分页程序,上传类等,也会提供用户自定义扩展类的接口。
2、ThinkPHP
1.好处
一、免费的,代码开源
二、单入口+模板引擎(thinktemplatexml)+MVC的一种的开发模式;
三、智能url路由 (0-3)
index.php?m=User&a=show&id=100
index.php/m/User/a/show/id/100
index.php/User/show/id/100
四、目录是自动建立
五、ajax+数据操做、表单验证等等都很智能
自动验证 自动完成 自动映射
ThinkPHP\CI\YII
2.框架下载
下载地址: www.thinkphp.cn
3.项目目录
3.一、index.php 项目入口文件
一、//检测PHP环境
if(version_compare(PHP_VERSION,'5.3.0','<')) die('require PHP > 5.3.0 !');
二、 //定义项目路径
define('APP_PATH', './Application/');
//注意此处后面必须加斜线
三、//加载框架入口文件 //注意 必定要严格区分大小写,防止项目迁移
require("./ThinkPHP/ThinkPHP.php");
//注意是requeire而不适用include 由于这个核心文件若是引入出错,那么整个项目就不必运行了
3.二、MVC对应的项目文件夹
M ---- ./Application/Home/Model
V ---- ./Application/Home/View
C ---- ./Home/Action/Home/Controller
4 ThinkPHP运用
4.1 URL四种访问方式URL_MODEL
1. 普通模式(URL_MODEL=0)
http://域名/项目文件夹名/入口文件?m=控制名&a=方法名&id=100
m:表明的是模块名(控制器名)
a:表明的模块的操做名(方法名)
/2015112/tp/index.php?m=Home&c=User&a=hello&name=tom&age=20
2. Pathinfo方式
http://域名/项目名/入口/模块名/方法名/键1/值1/键2/值2
http://localhost/2015110/middle/thinkphp/index.php/Index/index/test/zzz/name/tom.shtml
三、rewrite模式
http://localhost/2015110/middle/thinkphp/index.php/Index/index/test/zzz/name/tom.shtml
有时候要把地址栏中的index.php去掉 localhost/.../hinkshop/Index/index
四、兼容模式
当默认服务器没法兼容pathinfo模式的时候
http://localhost/2015110/middle/thinkphp/index.php?s=/Index/index/test/zzz/name/tom.shtml
注意:URL模式的更改在配置文件中的Home/Conf/config.php中更改URL_MODEL的值来实现的
4.二、TP:跳转方法
一、提示性信息页面模版 ThinkPHP/tpl/dispatch_jump.tpl
$this->success(提示性信息,U(Action/Method));
$this->error(提示性信息);
也能够自定义跳转模板,在config.Php文件中添加以下配置项:
'TMPL_ACTION_ERROR' => 'Public/error';
'TMPL_ACTION_SUCCESS' => 'Public/success';
就可使用本身定义的配置模版啦
二、页面重定向
当程序在一个方法里面想跳转另外一个方法时候,须要传递数据过去!
Eg: 传值形式相似于U
//重定向到New模块的Category操做
$this->redirect('New/category', array('cate_id' => 2), 5, '页面跳转中...');
·单纯的URL跳转
redirect('http://www.baidu.com', 5, '页面跳转中...');
函数的redirect(“url地址”,5,'页面跳转中...')只能跳转本控制器
注意两种用法的区别:
第一种是类的成员方法$this->redirect(),第二种是普通函数,直接使用
4.3 调用模版:
一个控制器对应一个模版目录
IndexController.class.php------>项目目录/view/Index/XXXX.html
$this->display(只有文件名没有后缀)若是控制里面方法不想调用与之名称一致的模版文件用此方法
$this->display();
注意:当display方法的值为空的时候表明调用与此控方法名相同模版名
// 主题 在./Application/Home/conf/config.php
'DEFAULT_THEME' => 'default', //默认模板主题名称
注意:若是设置了主题(default),为了防止模版路径过深
配置:TMPL_FILE_DEPR =>"_"
全部模版文件:./Application/Home/view/default/控制器名_XXXX.html
控制器名_模版名.html
4.4 debug调试模式
1.index.php------------>define('APP_DEBUG', true);
开启trace追踪页面
2./App/conf/config.php------------->"SHOW_PAGE_TRACE" => true,
3.'SHOW_ERROR_MSG' => false,
//显示配置项“ERROR_MESSAGE”,3.2中设置为false,true反而不显示错误信息
//app_debug开启的话,强制忽略此时show_error_msg
"ERROR_MESSAGE"=>"据说丑的人都会犯这个错",
4.'URL_HTML_SUFFIX' =>'html|shtml|htm', // URL伪静态后缀设置
5. 配置文件
惯例配置文件
/ThinkPHP/conf/convention.php 项目默认配置,不要在此文件里面修改配置项的值
项目配置文件
/Application/Home/conf/config.php 配置项目里一些信息,能够自定义配置,
优先级 C()>当前模块config.php>Application/Common/conf/config.php> convention.php
return array(
"配置项" =>值,
....
)
在代码中可使用系统提供的C函数
1. 读取 $变量 = C("配置项名称");
2. 修改 C("配置项的名称","值")
3. 动态配置 C("动态的配置项名称",值)
6.函数库
系统函数库
ThinkPHP/common/
-common.php(<3.1) 是全局必须加载的基础函数库,在任什么时候候均可以直接调用
-functions.php是框架标准模式的公共函数库,其余模式能够替换加载本身的公共函数库或者对公共函数库中的函数进行从新定义
-runtime.php(<3.1)是框架运行时文件,仅在调试模式或者编译过程才会被加载,所以其中的方法在项目中不能直接调用
3.2版本common.php和~runtime.php已经不存在,合并为functions.php
项目函数库
Application/Home/common/
项目函数库一般位于项目的Common目录下面,文件名为function.php,不能写错
函数使用:
引入函数所在命名空间
Namespacename\funcname();
7. 控制器的使用
7.1控制器之间的调用
一、本控制器调用其的控制器
$obj = A("控制器名");
eg: $Good = A("Good") //不是goodController
二、调用须要的方法
对象->方法名();
eg:
$Good->getHotGood();
做用:数据[代码]重用!
注意:在被调用的控制器里面那个方法 不能在调用模版了!数据以返回值的形式返回。
7.2 thinktemplate 模版引擎
一、调用模版:
$this->display();调用与此方法名一致的模版文件
$this->display(只有文件名没有后缀)
若是控制里面方法不想调用与之名称一致的模版文件用此方法
二、在展现模版以前,TP给我提供了两种往模版进行赋值的方法:
· $name = “张三”;
$this->name = $name;
$this->assign("模版变量名",php中的数据|变量)->assign(‘sex’,’xx’)->assign(‘age’,20)->display(“index”)
thinkPHP模版边界符默认 { }
前台使用:{$username}
'TMPL_L_DELIM'=>"{",
'TMPL_R_DELIM'=>"}"
注意:数组在模版中取值,能够是$arr[‘name’],也能够是$arr.name。
可是在模版中的数组元素值须要取值并运算的时候 只能使用 []的取值形式
模版变量也能够注释掉 {//$name}
模板引擎:
tp模版中的魔术变量
__ROOT__:会替换成当前TP项目的根目录(不含域名)
__APP__:会替换成入口文件地址(不含域名)
__MODULE__:会替换成当前模块的URL地址(不含域名)
__CONTROLLER__(__或者__URL__兼容考虑):会替换成当前控制器的URL地址(不含域名)
__ACTION__:会替换成当前操做的URL地址(不含域名)
__SELF__:会替换成当前的页面URL(入口文件)
__PUBLIC__:会被替换成当前网站的公共目录一般是 /Public/
注意:魔术方法无疑是提供了很大的方便性,可是当咱们的跳转或者传值很复杂的时候,能够考虑模版中的{:U()}函数
8.模版中的控制结构
8.1: if结构
<if condition="$条件">
代码块
<elseif condition="条件"/>
代码块
<else />
代码块
</if>
eg:
<if condition="$username=='admin'">
管理员
<else />
非管理员
</if>
eq或者 equal: 等于 ==
neq 或者notequal:不等于 !=
gt: 大于 >
egt: 大于等于 >=
lt: 小于 <
elt: 小于等于 <=
heq: 恒等于 ===
nheq: 不恒等于 !==
8.2 switch结构:
<switch name="uname" >
<casevalue="admin">管理员</case>
<casevalue="admin1">注册用户</case>
<default/>
普通会员
</switch>
注意:
1.switch的name值,不能带$符号,不然就编译成变量的变量
2. value的值 无论什么类型都得带上引号
3.<switch></switch>中间不能听任何注释
8.3 TP模版标签
一、模版中的临时变量
<assignname="varname" value="123"/>
注意: value的值必须带上引号
二、判断变量是否等于某个值
<eq name="var_name(无$)" value="value(值)">(内容1)<else/>内容2</eq>
<neqname="var_name(无$)" value="value(值)">(内容1)<else/>内容2</neq>
三、判断变量是否为空
<emptyname="变量">1<else />2</empty>
<notemptyname="变量">1<else/>2</notempty>
四、判断变量是否被赋值
<present name="qe">1<else/>2</present>
<notpresentname="">1<else/>2</notpresent>
// empty和present的区别在于空字符串的识别,$a = “”. empty认为值为空,可是present认为已经被赋值。其余状况就同样了
五、判断某个变量是否等于多个值中的一个
<in name="变量名" value="值1,值2,值3">1<else/>2</in>
等同于:
if(in_array($varname,array(值1,值2,值3))){
echo1;
}else{
echo2;
}
<notin name="变量名" value="值1,值2,值3">1<else/>2</notin>
六、区间判断
<between name=’var’ value=’start,end’></between>
七、常量的定义:
<define name="DB_HOST"value="localhost"/>
<definedname="DB_HOST">1<else/>2</defined>
<ifcondition="defined('DB_HOST')">
1
<else />
2
</if>
if(defined("DB_HOST")){
echo1;
}else{
echo2;
}
注意:模版中的常量输出 {$Think.const.HHH}或者{:HHH}
8.4 标签中的代码直接输出 模版代码不解析
<literal>
{$tag}
</literal>
8.5 在模版中直接写PHP代码
<php>
echo 1;
</php>
||
<?php echo 1;?>
8.六、模版中的三元运算符
{ $var>10?”yes”:”no” }
模版中的三元运算符等同于PHP中的三元运算符,而且写法规则也是同样的
8.七、循环结构:
for循环
<for start=’100’ end=’0’ comparison=”elt” step=-1 name=’i’>
</for>
Start : $i=100;
Comparison: elt 表示小于等于,固然也能够切换其余比较符号
End: $i=0; $i<=$end
Name: $i
在for标签中 能够省略comparison,默认就是start<end
foreach
<foreach name="变量名" item="vo"key="k">
{$vo}
</foreach>
name:被遍历的数组----->从php页面传过来的模版变量,无$符号
item:数组的元素 value的变量名
{$vo.键名} === {$vo["键名"]}
Volist
标签主要用于在模板中循环输出数据集或者多维数组
<volist name="list"id="vo" offset="5" length='10' mod=’2’ empty=”对不起,数组不存在” >
{$mod} {$vo.name}
</volist>
Name:遍历的数组的名称
Id:每一个数组元素值的表示符号,等同于foreach中的 $key=>$vo中的$vo
Offset:数组元素起始下标
Length:循环的数组元素个数
Empty:当遍历的数组不存在的时候,执行该句输出
Mod:做为取模的参数使用的
在遍历内部用$mod来接收当前记录索引值对mod取余的结果
Key: 当不定义时,可使用{$key}表示标识符,使用{$i}标识当前是第几回循环
而定义key属性的时候,属性值不为key时,都表示为第几回循环。
8.8 函数的使用在模版中使用的是PHP的函数
{$webTitle|md5|strtoupper|substr=###,0,3|。。。}
编译后的PHP代码就是:
<?phpecho (substr(strtoupper(md5($webTitle)),0,3)); ?>
###表示传递实参数是当前的那个标量
{$add_time|date="Y-m-d H:i:s",###}
注意:在使用模版函数的时候,何时会用到###???
在模版中使用函数时,若是该变量不是函数的第一个参数的时候,在后续的参数设置过程当中须要用###来代替本变量,可是若是本变量原本就是做为第一个形参传递到函数中的时候,就能够把###省略掉了
8.九、系统变量
模板引擎还支持系统变量和系统常量、以及系统特殊变量的输出。它们的输出不须要事先赋值给某个模板变量。系统变量的输出必须以$Think.打头,而且仍然能够支持使用函数
Eg: {$Think.now} 以默认格式获取当前的日期时间(非时间戳格式)
默认常量,当前时间戳
{$Think.const.NOW_TIME|date='Y-m-d H:i:s',###} 把当前时间戳转换成指定日期时间格式
{:NOW_TIME|date='Y-m-d H:i:s',###}这种有编译错误
8.10模版中文件的引入
<include file="路径+文件" />
用法1: <includefile="./App/Tpl/default/head.html" />
这种写法中,必须从index.php项目入口文件开始写,并且模版文件也必须带上后缀
用法2:
<include file="Pub/header" /> 或者 <include file=”Pub:header”>
这种写法是指 引入某个控制器的某个方法,
而该方法会自动调用与方法名相同的模版名,因此此时是不须要加上后缀的。
css|js|images|文件的引入:
<importtype='js' file="Js. user" /> //引入js文件的名称为user.js
<import type='css' file="Css.style,Css.index"/> //引入的css文件名为style.css和index.css
上面的方式默认的import的起始路径是网站根目录下Public目录,而且默认的type就是js
也能够以下引入:
<jsfile="__PUBLIC__/Js/Common.js"/>
<cssfile="__PUBLIC__/Css/common.css"/>
注意:外部的JS和外部的CSS中使用到的图片所有都是用相对路径。
Css的相对路径是相对于CSS文件自己,因此是../images/xxx.jpg
可是JS的图片是相对于模版目录,并且忽略主题设置,因此是 ../../Public/images/xxx.jpg(3.1)
在3.2里面则直接以入口文件为相对路径“./Public/img/xxx.jpg”
能够以服务器根目录/来设置
九、数据库链接
在配置文件中做以下设置:
'DB_NAME' =>'thinshop', //数据库名
'DB_USER' => 'root', //用户名
'DB_PWD' => '', //密码
'DB_PREFIX' => '', //数据库表前缀
'DB_CHARSET' => 'utf8', //数据库编码默认采用utf8
ThinkPHP中不须要用户本身去建立数据库链接或者实例化数据库对象,只有当你去实例化模型层的时候,基类Model才会自动帮你链接数据库
十、实例化模型层
一、实例化标准模型(基础模型基类model)
a) $obj =new Model(‘user’);
b) $obj =M(‘user’);
注意:
在TP的要求中,实例化基础模型层的时候后,M的参数必须是一张存在的表
二、实例化自定义模型层
a) $obj =new UserModel()
b) $obj =D(‘User’);
注意:D方法和M方法的区别
D和M均可以实现对表对象的实例化,对表的CRUD操做也都是同样的,不一样的地方在于,D方法实例化一个表对象的同时也表明着实例化了一个模型层的类文件,因此D方法既能够像M同样操做数据库,也能够用本身的模型层文件中的自定义的方法,天然在功能上就比M强大了一些,固然,运行速度也就降了下来。
还有,当模型层文件不存在的时候,D===M。由于在编译过程当中,发现须要实例化的模型层文件不存在,那么,对D的编译就会变成对M的编译。
三、实例化公共模型层 extends
a) 当咱们须要每个模型都须要额外的方法时候,为了不每一个模型都要作一样的处理,那么咱们选择设置一个公共的模型层。
b) 实现方法是 让这个CommonModel类继承 Model类,而后其余的类所有都继承CommonModel类
四、实例化空模型层
$obj = M();
a) 为了让不熟悉TP框架的ORM的人能快速上手TP的数据库操做,ThinkPHP提供了空模型层的概念
或者 有某种数据库操做很是很是复杂,复杂到ORM处理起来很是困难的地步,这个时候推荐你们使用空模型层的概念直接进行底层数据库操做
b) 这个空模型层只有两种方法
一、$obj->query();
Query对查询操做的返回是数组,对增删改的返回是空数组
二、$obj->execute();
Execute对查询操做的返回是查询的记录数,对增删改的返回是影响行数
因此:增删改使用execute方法,而查询则使用query方法。
Dump函数:TP系统提供的输出数组的方法
$obj->getLastSql():能够输出最后一个sql语句,能够用他来排除咱们后期ORM语句组装产生错误 别名 _sql();
或者经过打开‘SHOE_PAGE_TRACE’=>TRUE的trace调试模式中的SQL选项卡来监视数据库操做
十一、数据库操做
11.一、增
insertinto表 (字段列表) values(对应的数据列表),(),(),()
insertinto表 set字段1=值1,字段2=值2.......
一、模型对象->add($data)
$data:一个一维关联数组,以键名做为表字段,以数组元素值
做为字段内容
返回值:lastInsertId
二、模型对象->addAll($data)
$data:一个二维关联数组,以表字段做为键名,以字段内容做为数组元素值
返回值:lastInsertId
注意add和addAll获取的lastInsertId的区别。
三、模型对象->data($data);
使用data方法来准备将要被插入表的数据
$data:一维关联数组,与前两条结构相同
$user->data($data)->add(); //连贯操做
吐槽声一片,不如直接$user->add($data)这种方法。
四、模型对象->create()
帮助用户快速过滤表单提交的数据。
Eg: $_POST = array(
‘name’=>’张三’,
‘pwd’=>”123456”
‘sub’=>注册
)
如上述表单提交的数组中,name、pwd都是user表的字段,也是本次操做所须要操做的内容,可是sub就明显不是数据库字段,在操做的时候就须要排除$_POST中的sub
$data = $user->create($_POST);
若是通过create操做以后,$data = array(‘name’=>’张三’,’pwd’=>”123456”),就可 以直接做为诸如add等方法的参数而使用了
注意:就像咱们建立的Model文件的名称必须和代表相同同样,
咱们建立的form的name的属性值也应该和表的字段名相同,这样才更符合tp的规则
11.二、 删除
delete from表名条件
$user->where("条件")->delete(); 返回影响的记录条数
$M->delete(主键值); //AR的模式操做
11.三、更新 save
update表名 set字段名=value,字段名=value,........ where条件
点击修改----->控制器方法(经过传值的数据的标识,获取数据,传入模版)----->编辑页面(把数据填入到表单对应的位置)----->更新(标识传入过去)------->控制方法里面(获取更新的数据的标识)---->更新
$user= M(‘user’);
$where = “id=3”;
$data[‘name’] =’新名称’//注意此时的data须要以数组形式存储须要修改的值 区别于where
$user->where($where)->save($data);
11.四、查询
基础查询
一、模型对象->find() 一条记录转化成一维的数据 字段名=>value
select* from表 limit 1
二、模型对象->select() 查询全部的记录 转化为一个二维的数组
条件查询
三、单条件
模型对象->where($where)->select()
Eg: $where =”name=’张三’”;
四、多条件查询时
模型对象->where($where)->select()
①、依旧是字符串:$where =”name=’张三’ and age=20 or.....”;
②、更倾向于使用数组
$where = array("字段1"=>值1,"字段2"=>值2)
注意:此时数组的多个条件之间是默认使用 AND来链接的!!而且数组条件会自动和表字段映射,过滤掉表中不存在的字段。
若是想要条件之间是OR,则须要在$where这个数组中添加一个这样的键值对 “_logic”=>”or”
eg: $where = array('id'=>6,'subject'=>"测试新闻",'_logic'=>"or");
表达式查询
五、若是条件中须要 > < != in not in between and 等查询条件时
格式: $where[‘字段名’] = array(‘表达式’,’条件’)
Eg:查询uid>3的信息
$where = array(‘uid’=>array(‘gt’,3));
$where = array('id'=>array('between','3,5'));
$where = array('id'=>array('notbetween','3,5'));
$where =array('id'=>array('in','1,3,5'));
$where =array('id'=>array('not in','1,3,5'));
$where =array('subject'=>array('like','%测试%'));
$where =array('subject'=>array('like',array('%测试%','%中%')));
//注意这里like的两个条件是用or来链接
$where =array('id'=>array(array('lt',2),array('gt',5),'or'));
$user->where($where)->select();
六、聚合函数的应用
Count $user->count(); 计算表中的数据条数
Sum $user->sum(‘mark’);
Max $user->max(‘mark’);
Min $user->min(‘mark’);
Avg $user->avg(‘mark’);
七、排序 order
$user->order("id desc")->select();
$user->order("id desc,name asc")->select();
$user->order(array("id"=>"desc","name"=>"asc"))->select();
八、字段筛选 field
field(“字段1,字段2”)选择须要查询的字段
$user->field("id,name")->select();
参2:true->取反 , false:默认
连贯操做:
$user->field("id,name")->select();
九、限制 limit()
limit(start,length);
$user->field("id,name")->order(‘idasc’)->limit(0,5)->select();
十、分页方法
TP内置了分页方法,用法和limit相似
Page(页码,每页条数) 每页条数默认是20条
$user->field("id,name")->order(‘idasc’)->page(1,5)->select();
可是咱们实际上用不到分页方法,由于TP还提供了分页类,完爆这种分页方法
十一、分组group
Group("addr");
与group相对应的方法 还有一个having
having(); 附加的条件
$user->filed(’addr,count(addr) as num’)->having(“score>90”)->group(‘score’)->select();
十二、多表查询 table
Table(array(‘a代表’=>’别名’,‘前缀_代表’=>’别名’))
前缀_tableName",能够经过任何一个模型层对象去调用数据库中任何一个表的数据内容
注意:是带有表前缀和后缀的表名,由于在table函数中没有增长前缀和后缀的功能
$data=M()->table(array(‘stu’=>’s’,’mark’=>m))->where(‘s.sid=m.sid’)->select();
1三、alias() :给表取别名
$M->alias(‘m’)->
1四、join方法
join()多表链接查询 默认:inner join
有表前缀的表须要带上表前缀
$M->join("表2 on表1.字段=表2.字段")......->select();
$data = M('user u')->join('messagem onu.uid=m.uid')->field("u.uname,u.addr,m.mcontent")->select();
一、默认是内链接,怎么改为左连接或者右链接??
二、如何进行3表或多表查询?
$data = M('user u')->join('inner join message m onu.uid=m.uid')->join('inner join response re onu.uid=re.reuid')->field('u.uname,u.addr,m.mcontent,re.recontent')->select();
内链接: $m->join("inner join表2 on表1.字段 =表2.字段")->join("innerjoin表3表2.字段 =表3.字段").......->select();
右链接: $m->join("rightjoin表2 on表1.字段 =表2.字段")->join("right join表3 on表2.字段 =表3.字段").......->select();
11.五、TP的ORM中事务的使用
事物:
$M->startTrans():开启事务; mysql_query("begin")
$M->commit():提交事务;
$M->rollback():回滚事务;
$M->startTrans();
$row=$M->where("id=".$id)->delete()
if($row){
$id2=$M->where("uid=".$id)->delete();
if($id2){
$M->commit();
}else{
$M->rollback();
}
}else{
$M->rollback();
}
11.六、经常使用的获取表信息、数据库操做信息的方法
模型对象->getDbError();//获得程序中,数据库操做中的错误 mysql_error();
模型对象->getLastSql();获取最后一条执行的sql语句 _sql()
模型对象->getDbFields():获得模型层中模型的数据库某个表中 字段信息
模型对象->getModelName():获得当前模型层中模型层名字
模型对象->getTableName():获得当前模型层中对应的表名
模型对象->getPk();获取当前操做数据表的主键名
11.七、动态查询
getBy字段(数据):查询某个表中有该字段值的记录;
该查询方式针对数据表的字段进行查询。例如,User对象拥有id,name,email,address等属性,那么咱们就可使用下面的查询方法来直接根据某个属性来查询符合条件的记录。
$User= M("user");
一、$data = $User->getById(100);== $data =M("user")->where("id=100")->find();
二、$data =$User->getByName("admin");==$data= $M->where("name='admin'")->find();
十二、数据库切换:
若是须要切换到另一个数据库(包括在相同和不一样的数据库类型之间切换)或者须要链接多个数据库进行操做不一样的数据,就须要使用ThinkPHP提供的数据库切换方法(M、db)
1. 直接连接
$m = M("表名","表前缀","数据库类型://用户名:密码@服务器名:端口号/库名");
$M =M("news","","mysql://root:@localhost/mid112");
2. 读取配置文件切换连接
$m = M('weibo','tk_','DB_CONFIG2');
DB_CONFIG2----->config.php
"DB_CONFIG2" => array(
'db_type' => 'mysql',
'db_user' => 'root',
'db_pwd' => 'admin',
'db_host' => 'localhost',
'db_port' => '3306',
'db_name' => 'tk89'
注意:在使用切
换数据库时,不能让两个库中的表名相同,不然在查询的时候,优先查询本身的表,只有当默认链接的库中表不存在的时候才会查询第二个链接(3.1是这样 3.2已经优化)
1三、控制器中用获得的常量:
echo MODULE_NAME;
echo APP_NAME; (3.1)
echo ACTION_NAME;
echo THINK_VERSION;
1四、TP的会话控制
session: 系统提供了Session管理和操做的完善支持,所有操做能够经过一个内置的session函数完成。
默认状况下,初始化以后系统会自动启动session,若是不但愿系统自动启动session的话,能够设置SESSION_AUTO_START为false,例如:
'SESSION_AUTO_START' =>false
session赋值:Session赋值比较简单,直接使用: session('name','value');
若是须要存储多个值的时候,只能一个一个赋值,数组形式的赋值是对session作配置,不是存储session信息:
session取值: $value= session('name');
session删除 : session('name',null);//删除name ;要删除全部的session,可使用session(null);
session判断: 要判断一个session值是否已经设置,可使用 session('?name');// true|false用于判断名称为name的session值是否已经设置
COOKIE: cookie()
Cookie设置 :setcookie("name",value,time,path,domain);cookie('name','value'); //设置cookie永不过时cookie('name','value',3600);//指定cookie保存时间
Cookie获取:$value= cookie('name'); 获取全部cookie信息$cookies = cookie();
Cookie删除:删除某个cookie的值,使用:cookie('name',null);要删除全部的Cookie值,可使用cookie(null);//清空当前设定前缀的全部cookie值
1五、TP模型扩展
ThinkPHP自己提供了丰富的模型扩展,目前提供的的扩展模型包括:高级模型(AdvModel)、视图模型(ViewModel)、关联模型(RelationModel)和Mongo模型都是继承Model类而且都经过了扩展完成了不少其余的功能。
Eg:高级模型 AdvModel
ThinkPHP\Library\Think\Model
扩展高级模型的使用:
在3.2以上版本,使用扩展模型须要带上命名空间use Think\Model\AdvModel;
①、自定义模型层的时候选择继承高级模型,而不是继承基础模型
Class UserModel extends AdvModel{}
②、让公共模型层 CommonModel.class.php继承高级模型
Class CommonModel extends AdvModel{}
③、经过switchModel()函数切换模型层
$User->switchModel("Adv")->top10();
④、直接经过M函数
M("AdvModel:User")->top10();
1六、几个须要用到模型文件的功能
一、字段映射:ThinkPHP的字段映射功能可让你在表单中隐藏真正的数据表字段,而不用担忧放弃自动建立表单对象的功能
Class UserModel extends Model{
protected $_map = array(
// "表单控件名"=>"数据库字段名",
"biaoti" => "title",
"neirong" => "content",
);
}
这样,在Action中使用create方法去过滤表单数据的时候就会根据$_map去作过滤了
二、自动完成
在Model类定义 $_auto属性,能够完成数据自动处理功能,用来处理默认值、数据过滤以及其余系统写入字段。
Eg:正常的表单处理过程须要对密码进行md5加密,在TP中,咱们就能够完成它的自动加密。具体作法是在对应的model类中定义$_auto变量,书写自动完成规则,这样,在使用create()完成表单过滤的同时,就已经完成了对password字段的md5加密了。
$auto = array (
array('password','md5',1,'function') // 对password字段在新增的时候使md5函数处理
);
三、自动验证
TP内置了数据对象的自动验证功能来完成模型的业务规则验证,而大多数状况下面,数据对象是由表单提交的$_POST数据建立。须要使用系统的自动验证功能,只须要在Model类里面定义$_validate属性,
protected $_validate = array(
array('verify','require','验证码必须!'), //默认状况下用正则进行验证
array('name','','账号名称已经存在!',0,'unique',1), // 在新增的时候验证name字段是否惟一
array('value',array(1,2,3),'值的范围不正确!',2,'in'), // 当值不为空的时候判断是否在一个范围内
array('repassword','password','确认密码不正确',0,'confirm'), // 验证确认密码是否和密码一致
array('password','checkPwd','密码格式不正确',0,'function'), // 自定义函数验证密码格式
);
定义好了$_validate以后,在进行create操做的时候,就会对表单的数据进行自动验证。若是验证失败,则create()返回false,能够经过模型对象->getError()的方法捕获验证失败的反馈信息
Eg:
$article = D("Article");
$data =$article->create();
if (!data){
//若是建立失败表示验证没有经过输出错误提示信息
exit($article->getError());
}else{
dump($data);
//验证经过能够进行其余数据操做
}
1七、thinkphp中ajax操做:
_param()
1) IS_AJAX,IS_POST,IS_GET:判断标签或者数据提交方式,
IS_AJAX:若是数据提交方式,是按照ajax提交方式提交的,那么他会返回正确,不然,返回错误.
2) ajax返回,返回的都是json数据:
ajaxReturn($data):返回ajax提交的结果
$data指返回的数据。
该数据能够是字符串,数值,或者数组
都会被ajaxreturn转换成JSON对象,方便前端jq,js操做。
3) ajax返回中也可使用: success()和error().
Eg: $this->seccess(“yes”,”Index/index”);
AJAX获取的返回信息:{"info":"yes","status":1,"url":"Index\/index"}
若是是error()的话,获取到的status则为0
4)设置ajax返回的数据样式配置:
'DEFAULT_AJAX_RETURN' =>'JSON', //默认AJAX数据返回格式,可选JSON XML ...
1八、数据分页:第三方的分页类 page类
F:\wamp\www\2015112\tp\ThinkPHP\Library\Think\page.class.php (第三方类库的使用)
1、利用Page类和limit方法
$page = new \Think\Page(总记录数,每页显示条数);
$User = M('User');//实例化User对象
$count = $User->where('status=1')->count();//查询知足要求的总记录数
$Page =new \Think\Page($count,25);//实例化分页类 传入总记录数和每页显示的记录数(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();//输出模板
2、分页样式定制
private $config =array(
'header' =>'<span class="rows">共 %TOTAL_ROW%条记录</span>',
'prev' => '<<',
'next' => '>>',
'first' => '1...',
'last' => '...%TOTAL_PAGE%',
'theme' =>'%FIRST%%UP_PAGE%%LINK_PAGE%%DOWN_PAGE%%END%',
);
3、实例
注意:使用limit方法的时候,参数必须是page类的成员变量
1九、验证码:
一、生成验证码
$Verify = new \Think\Verify();
$Verify->entry();
二、验证码的显示:
Img标签的src属性值直接设置为生成验证码的方法便可
Eg: <img src="{:U('Home/User/verify')}" id="yzm">
注意:验证码生成以后 是直接加密以后存储在session中的,且默认设置包含验证码有效时间1800S和验证成功以后,session存储的验证码信息直接清空
四、验证码配置
$config=array{
'useImgBg' => false, //使用背景图片
'fontSize' => 25, //验证码字体大小(px)
'useCurve' => true, //是否画混淆曲线
'useNoise' => true, //是否添加杂点
'imageH' => 0, //验证码图片高度
'imageW' => 0, //验证码图片宽度
'length' => 5, //验证码位数
'fontttf' => '', //验证码字体,不设置随机获取
'bg' => array(243, 251, 254), //背景颜色
'reset' => true, //验证成功后是否重置
);
注意:
一、若是图片出不来,试试将ob_end_clean()添加到实例化对象以前
二、不要使用其中的imageH和imageW,如需改变大小直接经过CSS操做<img>
三、中文验证码须要字体文件,若是中文不显示,请检查ThinkPHP\Library\Think\Verify\zhttfs中是否包含了中文字体文件
三、验证验证码:
使用ajax调用Verify类的Check方法便可!
<script>
functioncheck(){
var val= $(".verify").val();
var data ="verify="+val;
$.post("{:U('Home/User/check_verify')}",data,function(re){
if(re==true){
$(".verify").css("border","1px solidgreen");
}else{
$(".verify").css("border","1px solidred");
}
})
}
$(".verify").blur(check);
$("#yzm").click(function(){
var num =Math.random();
var url ="{:U('Home/User/verify/asd/"+num+"')}";
$(this).attr("src",url);
check();
})
</script>
</div>
注意:验证码刷新功能须要带上一个随机数,以保证不会读取ajax缓存致使没法刷新
20、文件上传: Library/ORG/Net/UploadFile.class.php 文件上传类
一、引入并使用
$upload = new\Think\Upload($config);
$info=$upload->uploadOne($_FILES['photo']);单文件上传
$info=$upload->upload(); //多文件上传
注意:
一、使用upload方法不须要任何参数,可是使用uploadOne方法,须要带上上传文件的信息
二、上传以后将会返回上传的文件的存储信息
Dump($info)查看文件信息
二、上传配置:
$config = array(
'mimes' => array(), //容许上传的文件MiMe类型
'maxSize' => 0, //上传的文件大小限制 (0-不作限制)
'exts' => array(), //容许上传的文件后缀
'autoSub' => true, //自动子目录保存文件
'subName' => array('date', 'Y-m-d'), //子目录建立方式,[0]-函数名,[1]-参数,多个参数使用数组
'rootPath' => './Uploads/', //保存根路径
'savePath' => '', //保存路径
'saveName' => array('uniqid', ''), //上传文件命名规则,[0]-函数名,[1]-参数,多个参数使用数组
'saveExt' => '', //文件保存后缀,空则使用原后缀
'replace' => false, //存在同名是否覆盖
'hash' => true, //是否生成hash编码
'callback' => false, //检测文件是否存在回调,若是存在返回文件信息数组
'driver' => '', //文件上传驱动
'driverConfig' => array(), //上传驱动配置
);
2一、获取ip:
系统提供了直接获取IP的函数
$ip = get_client_ip();
若是想要获取ip地址所在区域,
$Ip = new\Org\Net\IpLocation('UTFWry.dat');//实例化ipLocation类参数表示IP地址库文件
$area = $Ip->getlocation($ip); //获取某个IP地址所在的位置
print_r($area);
UTFWry.dat下载地址:http://www.thinkphp.cn/extend/270.html
解压以后放在和IpLocation类同级目录
2二、项目分组:
对模块的访问是自动判断的,因此一般状况下无需配置模块列表便可访问,在部署模块的时候,默认状况下都是基于相似于子目录的URL方式来访问模块的,例如:
http://serverName/Home/New/index//访问Home模块http://serverName/Admin/Config/index //访问Admin模块http://serverName/User/Member/index//访问User模块
一、设置项目中容许的模块
若是咱们须要设置分组的话,须要手动更改tp\Application\Common\Conf\congfig.php,添加以下配置:
'MODULE_ALLOW_LIST'array'Home''Admin''User' => (,,),
'DEFAULT_MODULE''Home'// 默认模块 => ,
二、拒绝访问模块
若是你的应用有不少的模块,你只是想禁止访问个别模块的话,能够配置禁止访问的模块列表(用于被其余模块调用或者不开放访问),默认配置中是禁止访问Common模块和Runtime模块(Runtime目录是默认的运行时目录),咱们能够增长其余的禁止访问模块列表:
// 设置禁止访问的模块列表
'MODULE_DENY_LIST'array'Common''Runtime''User' => (,,),
三、模块映射
若是不但愿用户直接访问某个模块,能够设置模块映射(对后台的保护会比较实用)。
'URL_MODULE_MAP'array'test''admin' => (=>),
注意:这里的映射指的是,隐藏admin模块,访问admin模块表面上体现的是访问test模块,设置了模块映射后,原来的Admin模块将不能访问,只能访问test模块。
咱们访问 http://serverName/Admin将会报模块不存在的错误,而 http://serverName/test 则能够正常访问Admin模块。
若是你同时还设置了MODULE_ALLOW_LIST参数的话,必须将容许模块列表中的原来的模块改为映射后的模块名,例如:
'MODULE_ALLOW_LIST'array'Home''Test''User' => (,,),
'DEFAULT_MODULE''Home' => ,
'URL_MODULE_MAP'array'test''admin' => (=>),
问题:
Q:加入作了模块映射,那么超连接跳转地址写映射前仍是映射后?
A:依然是映射前,会自动映射。好比,把Admin影射成Test,可是实际写的U用的依然是Admin
函数:
A函数 控制器之间的调用
D函数 D函数用于实例化Model对象(模型文件必须存在)
M函数 M函数用于实例化一个没有模型文件的Model
C函数 配置文件操做
U函数 Url生成
S函数 数据缓存
F函数 文件缓存
I函数
$uname =I("get.password","","trim,md5"); //能够设置多个过滤规则
session函数
cookie函数