1. 概述
目录结构:
根目录结构
ThinkPHP/: 框架目录
Public/: 资源目录
Application/: 项目目录
index.php: 入口文件
项目目录结构
Common/: 公共模块
Common/: 模块公共函数 function.php
Conf/: 模块公共配置
Home/: 自定义模块 //添加新模块,在入口文件: define('BIND_MODULE', 'Admin');用后需要删除
Common/: 模块函数 function.php
Conf/: 模块配置
Model/: M层
Controller/: C层
View/: V层
Runtime/: 运行时目录 //define('RUNTIME_PATH', './run');需要一直在入口文件处定义
Cache/: 缓存
Data/: 数据
Logs/: 日志
Temp/: 缓存目录模块设计
调试模式:
define('APP_DEBUG',true); index.php
定义模块配置文件
define('CONF_EXT', '.ini'); 默认使用return array(a=>'one');支持 PHP数组,INI,JSON,XML,YAML
控制器: 每个模块下都有默认首页控制器 IndexController.class.php,其中控制器名为:index
<?php
namespace Home\Controller;
use Think\Controller;
class IndexController extends Controller {
public function func(arg='val'){ //对于private,protected不可通过 URL的形式访问
$this->show('Hello TP!');}
}
访问模块函数: 默认会访问Home模块下的Index控制器的index方法
index.php/模块名/控制器名/方法名/参数/参数值
模板视图渲染: 内置编译型模板,支持原生模板,提供Smarty在内的模板引擎
默认模板定位: View/控制器名/操作名.html ,如果ThinkPHP找不到控制器对应URL的方法,会直接渲染模板
控制器方法中:
$this->assign("title","变量内容");$this->display();
模板文件:
{$title};
2. 数据库操作(CURD): 在Common/Conf/config.php中定义
'DB_TYPE'=>'mysql',// 数据库类型
'DB_HOST'=>'127.0.0.1',// 服务器地址
'DB_NAME'=>'tpdb',// 数据库名
'DB_USER'=>'root',// 用户名
'DB_PWD'=>'',// 密码
'DB_PORT'=>3306,// 端口
'DB_PREFIX'=>'tp_',// 数据库表前缀
'DB_CHARSET'=>'utf8',// 数据库字符集
控制器方法:
$user = M('User');
$rs = $user->find(1);
$this->assign('user',$rs);
$this->display();
模板文件:{$user.name} // 或对象['列名']
添加记录(Create)
1. 初始化模型对象: $user = D('User'); //D方法需要找模型类,当前模块/Model/UserModel.class.php
2. 为模型对象添加数据:$user->create(); 或 $user->name = 'user1'; //create方法在表单提交默认使用控件的name值做列名
3. 添加到数据库 add方法: $user->add(); //可使用参数$data,$data['name'] = 'user1';
其中 add()方法返回记录的自增主键值/插入数据个数,false表示失败
更新操作(Update)
1. 创建模型并根据主键保存: $m = D('User'); if($m->create())$result = $m->save();
2. 根据查询条件保存 save方法: $data['name'] = 'abc'; M('User')->where('id=1')->save($data);
3. 修改查询记录某个字段 setField方法: M('User')->where('id=1')->setField('name','newName');
读取操作(Read):AR模式(ActiveRecord)
1. 实例化基本模型: $m = M('User');
2. 查找数据 find和getField: $data = $m->find(1); 或 $data['name'] = $m->where('id='.$id)->getField('name');
3. 赋值模板: $this->assign('data',$data); 取 {$data.name}
删除操作(Delete)
1. 实例化模型 $m->M('User');
2. 删除操作 delete方法: $m->delete('1,2');删除主键为1,2的记录 $m->where('status=0')->delete();条件删除
查询语言:$user = M('User');
基本查询: $user->where('name like a% OR id<10')->select();
数组和表达式: $c['name']=array('like','a%');$c['id']=array('lt','10');$c['_logic']='OR'; $user->where($c)->select();
其中表达式: (N)LT,(N)EQ,(N)GT,like,between,in,EXP;
其中EXP为SQL语句,EXP同样适用于save方法;$data['score']=array("exp","score+1");$user->where('id = 5')->save($data);
快捷查询: $user->where($cond)->select();
不同字段相同值: $cond['status|score'] = 0; //OR逻辑,注意|与&不可同时使用
不同字段不同值: $cond['status&name&score'] = array('1','user1',array('gt','100'),'_multi'=>true);//AND逻辑
复杂逻辑:
同一字段不同条件: $cond['name'] = array(array('like','b%'),'Abraham','OR');
改变优先级的三种模式:$cond['score']=array('lt','100');
_query: $cond['_query']='status=0&name=Abraham&_logic=OR'; SQL: score<100 and (status=0 OR name = 'Abraham')支持简单等值
_string: $cond['_string']='status=0 OR pwd is NULL'; SQL: score<100 and (status=0 OR pwd is null)支持复杂逻辑
_complex: $c1['status']=array('neq','0');$cond['_complex']=$c1; SQL: score<100 and (status!=0)
聚集函数:count,sum,max/min/avg;
ThinkPHP为聚集函数封装了同名方法: $user->where('status!=0')->max('score'); $user->count();
非ORM非AR查询:$m = new Model();无需指定具体数据模型,use ...,Think\Model;
query($sql,$parse=false):无解析得执行$sql,查询失败返回false;否则返回结果集
execute($sql,true):有解析地执行写操作$sql,返回false或影响记录数
动态查询:$m = M('user');
getBy: $user = $m->getByName("user1"); 获取整个数据对象
getFieldById: $name = $m->getFieldById('3','name'); 获取数据对象某个字段
子查询:$m = new Model();
生成子查询语句:select(false),buildSql()比select(false)生成的语句左右多了括号;
$subsql = $m->field('id,name')->table('tp_user')->group('status')->order('score')->buildSql();
使用子查询:
$m->table($subsql)->where()->order()->select();
连贯操作: 所有连贯操作方法返回当前模型的实例对象,连贯操作方法没有顺序,不影响下一次查询
where* 查询或者更新条件 字符串、数组和对象 , 如果没有where调用,不会更新和删除;
table 定义目标表名(全名含前缀) 字符串和数组 , 默认使用当前模型对应的表
$m->table(array('db_name.db_table'=>'table_alias'))->select();
alias 给当前数据表定义别名 字符串
table("db_table")->alias("mytable");
data 模型数据对象 数组和对象
data($d)->add();$m->data($d)->where('id = 3')->save();
field 定义查询的字段(支持字段排除) 字符串和数组
field(array("id","score"=>'alias_score'))->select();
field("id",true)->select();//字段排除
order 对结果排序 字符串和数组
order(array('score'=>'desc'))->select();
limit 限制查询结果数量 字符串和数字
limit('offset,length');
page 查询分页(内部会转换成limit) 字符串和数字
page(1,50);
group 对查询的group支持 字符串
having 对查询的having支持 字符串
$m->group('score')->having('score>59')->select();
join* 对查询的join支持 字符串和数组,如果参数为数组,不可多次使用
join(array('tp_note on tp_user.id=tp_note.uid'));
union* 对查询的union支持 字符串、数组和对象,每个Union都是一个独立SQL语句
table('tp_user')->union('select * from `tp_admin`',false)
注: UNION ALL只是简单把数据结果合并,不会去重,但效率高于UNION;
distinct 用于查询的distinct支持 布尔值
field(name)->distinct(true);
lock 添加行级锁 布尔值
lock(true),其他会话不可更新,直到此会话结束 或 提交回滚
filter 数据过滤 字符串
filter("strip_tags");filter('htmlspecialchars');在写入时候过滤
bind* 用于数据绑定操作 数组或多个参数
token 用于令牌验证 布尔值
comment 用于SQL注释 字符串
index 用于数据集的强制索引 字符串
strict 用于数据入库的严格检测 布尔值
scope* 用于命名范围 字符串、数组
relation 用于关联查询(需要关联模型扩展支持) 字符串
自动验证: 保存前验证,create方法触发
规则定义: array(表单字段,规则,错误提示 [,条件,附加规则,验证时间] )
表单字段: 一般为控件的name;
规则:可以填''配合附加规则使用,快捷正则验证有: require必填,number数字,email邮箱,url地址
错误提示: 验证失败后的提示信息,通过 $d->getError()获取;
条件:0存在就验证(默认),1必须验证,2非空值验证,有对应常量self::EXISTS/MUST/VALUE_VALIDATE,
验证时间:1新增时,2更新时,3全部情况(默认),对应self::MODEL_INSERT/UPDATE/BOTH;
附加规则:
regex: 表示前面的规则是一个正则表达式串(默认) '/^[a-zA-Z_]\w{5,}/'
function: 规则是公共函数名
callback: 规则是当前模型的方法
confirm: 规则是字段,两个字段需相等
[not]equal: 规则是一个值,要求与此值(不)等
[not]in,[not]between: 规则是逗号分隔的串或数组,要求(不)在此范围
length: 规则是数字或"x,y";验证长度
expire: 规则是"2117-3-10,2017-3-18"或者"NOw_time,time()+60*15",要求在此时间之内,表单字段随意填写; 时间戳转换date("Y-m-d H:i:s",time())
unique: 规则为'',会自动查询数据库,保持数据唯一,不可用于判断主键
ip_allow/deny: 规则为逗号分隔的ip地址,表示允许/禁止IP
静态验证: 在Model/UserModel.class.php模型中,为模型添加字段 protected $_validate = array(array(...),); if(!$d->create()){//必须使用D方法构造模型}
动态验证: 定义一个二维规则数组$rule, if(!$m->validate($rule)->create() )表示验证出错
自动完成: 默认字段写入,安全字段过滤和处理(如密码加密),create方法触发并返回完成后的对象
规则定义: array(表字段,规则[,条件,附加规则])
表字段: 数据库表字段名;
条件: 1新增时(默认),2更新时,3全部情况,对应self::MODEL_INSERT/UPDATE/BOTH;
规则: 配合附加规则使用,没有附加规则时候此值为默认值
附加规则:
function: 表示规则是一个公共函数名,函数返回值为默认值
callback: 规则是当前模块的方法
field: 规则是其他字段名,使用其他字段值填充
string: 默认,规则是默认值
ignore: 提交时为空 则忽略
静态完成: 在模型中添加字段 protected $_auto = array(array(...),);必须使用D方法构造模型
动态完成: $m->auto($rule)->create();$m->add();
*create()方法说明;
create方法会自动根据当前提交的表单name封装模型数据,并舍弃数据库表中不存在的字段
此方法返回封装创建的模型对象,在save或add方法调用后$m就会失效;
$user = M("User");
$rule = array(array("pwd","md5",3,"function"),array("regist_time","time",3,"function"));
$user->auto($rule)->create();
$user->save();
3. 控制器
变量获取:
I方法获取: I('数据源类型.[变量名]/转型修饰','默认值','过滤器','其他数据源')
数据源类型:get,post,put,param(默认,get->post->put);request,session,cookie,server;globals,path,data其他数据源
过滤器:配置默认过滤器: 'DEFAULT_FILTER'=>'htmlspecialchars,strip_tags'
过滤器可以是:内置过滤函数名,filter_var的第二个参数的域filter_list,正则表达式(/reg/);false/''表示不过滤
*filter_list:int,boolean,float,validate_regexp,validate_url,validate_email,validate_ip,string,stripped,encoded,special_chars,unsafe_raw,email,url,number_int,number_float,magic_quotes,callback
转型修饰符:s字符串, d整型, b布尔, a数组, f浮点数
Action参数绑定: 为控制器方法传递参数 'URL_PARAMS_BIND'=>true;默认打开绑定
按变量名绑定:Home/Controller/function/ arg2/val2/arg1/val1
按变量顺序绑定: 在config中:'URL_PARAMS_BIND_TYPE'=>1 , Home/Controller/function/ val1/val2 ; 只支持pathinfo和兼容模式
空控制器与空操作(访问出错处理)
空操作: 访问控制器中未定义的方法时候,默认调用 public function _empty();方法,此方法可使用参数
空控制器: 访问模块中未定义的控制器时,默认调用 class EmptyController extends Controller;的index方法,也可为空控制器定义_empty方法
初始化,前置/后置操作
初始化操作: public function _initialize();此方法在本操作器所有方法执行前都会执行一次
前置操作:_before_fxx() fxx方法执行前都会执行此方法,修饰符需为public
后置操作:_after_fxx(); 此方法在执行完fxx方法,且fxx中并未使用exit或error方法的话,会被执行
页面跳转和重定向
success和error: 模板 'TMPL_ACTION_SUCCESS'/'TMPL_ACTION_ERROR'=>'View/Public/xx.html'
$this->success("mes",$_SERVER['HTTP_REFERER'],1); 提示信息,跳转地址(./M/C/A),等待时间/秒
$this->error("mes","history.back(-1)",3);
自定义跳转模板可使用如下变量: $message|$error,$jumpUrl,$waitSecond分别对应方法参数
redirect('C/A或URL','访问参数',等待时间/秒,提示信息);
页面请求与Ajax返回
判断请求方式: 系统常量:IS_XXX,REQUEST_METHOD;(非jquery的IS_AJAX判断需要在表单中隐藏一个域ajax="",域名通过VAR_AJAX_SUBMIT配置)
AJAX返回: $this->ajaxReturn($data [,"json"] ); 'DEFAULT_AJAX_RETURN' => 'JSON' 配置了默认返回格式,
JSONP返回: 'DEFAULT_JSONP_HANDLER' => 'jsonpReturn': $this->jsonpReturn($data)会自动传参给'VAR_JSONP_HANDLER' => 'callback' 指定的函数
绑定操作到类: 'ACTION_BIND_CLASS'=>true;
控制器位置: app/Home/Controller/Index/index.class.php
namespace Home\Controller\Index;
use Think\Controller;
class index extends Controller{
public function run(){
echo "每个类只有唯一的操作,支持前/后置操作,空控制器与空操作";
}
public function _before_run();
public function _after_run();
}
空操作: app/Home/Controller/Index/_empty.class.php
空控制器: app/Home/Controller/_empty/index.class.php
监听器: Home/Event/Login.class.php , namespace Home\Event; 监听器模式
实例化: $ev = new \Home\Event\Login(); //A("Login","Event");
$ev -> notify($name); // 等价 R("Login/notify",'name=MC','Event');
4. 视图(模板)
模板控制参数:
'DEFAULT_V_LAYER' => 'View' //模板目录名
'TMPL_TEMPLATE_SUFFIX' => '.html' //模板后缀名
'TMPL_FILE_DEPR' => '-' //模板寻址
'VIEW_PATH' => './Public/Templates/'//模板寻址路径 ./Public/Templates/Controller-function.html
define('TMPL_PATH'.'./Public/Templates/'); //效果同上,上条配置优先
默认模板定位:./Application/Home/View/[Theme]/Controller/function.html : 默认不启用主题
模板渲染:
$this->display();
[theme("blue")->]display("folder:tmpl",'utf-8','text/html');
display("./Public/Templates/my.html")
$this->fetch("Control:tmpl"); 并不输出,返回渲染以后的内容,$this->show($content,'utf-8','text/html');
模板赋值与变量输出: $this->assign('data',$data);
'TMPL_L_DELIM' =>'{','TMPL_R_DELIM' =>'}';
{$name} 注意此处{$之间不可有任何其他字符(++,--除外)
{$arr['name']},{$arr.name} 数组
{$obj->name},{$obj:name} 对象
系统变量:
{$Think.server.var} server,session,get,post,request,cookie,
{$Think.const.MODULE_NAME} 系统常量
{$Think.config.key} 配置值
输出前修饰:
{$time|date='Y-m-d',###} 编译后: date('Y-m-d',$time);
{:substr(strtoupper($name),0,3)} <=> {$name|strtoupper}
{$name|substr=0,3|default='游客'} 函数和默认值 配合使用
{++$a-($b*10/$c)%10} , {$condition ? 'OK' : 'ERR' } : 注意,这些运算符中的表达式,都不支持.语法
循环遍历:$this->assign('data',$d);
<volist name="data" id='vo' offset='0' length='5' mod='5' empty='...'>
<eq name="mod" value="0">{$vo}</eq>
<eq name="mod" value="1">*{$vo}</eq>
<br/>
</volist>//其中,name=":f('arg')",其他位置可以放变量(empty='$empty')
<foreach name='data.arr' item='vo'> {$vo.name} </foreach>
条件输出:
<switch name="data.sex|settype='bool'">
<case value="1|true|$boy" break='0'>Girl</case> //默认break=1,表示一旦匹配后面的不再匹配
<default/>Boy
</switch>
比较标签: (n)lt , (n)eq , (n)heq , (n)gt 分别表示 <,==,===,>
<xx name="data:sex|settype='bool'" value="$boy">
满足条件输出
<else/>不满足条件输出
</xx>
范围标签: (not)in , (not)between
<in name='data.num' value='$range'> //此次$range可为数组或 , 分隔的字符串
范围内<else/>范围外</in>
<between name='Think.get.id' value='$range' >//支持数字("1,40"),字符("A,Z")
<else/></between>
赋值判断: present , empty , define : 是否赋值,是否为空,是否预定义
<present name="Think.get.id">已赋值<else/>未赋值</present>
原生代码: <php>echo "Hello World";</php>
引用模板:
<include file="Public/header,./Public/nav.html" title="使用标题[title]" />
//注意这样使用变量必须在当前控制器赋值,且改变模板不会重编译,部署需要删除缓存或打开debug模式
启用布局模板: 先渲染layout模板,在渲染当前控制器模板,最后替换{__CONTENT__},当前模板若包含{__NOLAYOUT__}则不渲染layout模板
layout.html:
<include file="Public:header" />
{__CONTENT__}
<include file="Public/footer" />
1.使用配置 : 'LAYOUT_ON' = true,'LAYOUT_NAME'='Public/layout'; 自动找当前模块下View/Public/layout.html
2.使用标签 : <layout name="Public/layout" replace="{__CONTENT__}"/> , 需关闭LAYOUT_ON否则会死循环
3.使用函数 : 在display前 layout("Public/layout");表示渲染使用布局,若已开启LAYOUT_ON,layout(false)会关闭本次渲染布局
5. 路由(URL配置)
TP支持的4中URL模式:
普通模式 : ?m=模块名&c=控制器&a=方法名&参数=值
PATHINFO : /模块名/控制器名/方法名/参数/值 或者 /模块名/控制器名/方法名?参数=值
可以在全局Common/Conf中自定义分隔符: 'URL_PATHINFO_DEPR'=>'-',启用路由需要支持PATHINFO
REWRITE : 可以在PATHINFO的基础上,去掉index.php
<1>. http.conf中的rewrite模块(LoadModule rewrite_module modules/mod_rewrite.so)
<2>. 在Directory标签中 AllowOverride ALL,使支持.htaccess文件
<3>. 在入口文件同级添加 .htaccess 文件
兼容模式: 使用 ?s=/ 替代 index.php/使支持PATHINFO效果
路由配置参数:路由是对URL寻址规则的定义,为每个URL定义一个真实访问路径
'URL_ROUTER_ON'=>true 开启路由
'URL_ROUTE_RULES'=>array() 路由规则定义
'URL_MAP_RULES'=>array() 静态映射定义
路由配置规则:'路由表达式'=>'路由地址和参数';系统会按定义顺序匹配路由规则,一旦成功就不会继续匹配
路由表达式:正则表达式+规则表达式,匹配模块名后面的路径串
正则:'/^路径1\/(\d+)$/'=>'index/f?arg=:1',子模式可以以 :x 的方式引用
规则:'self/:arg^index-add$'=>'index/f', 这样:arg就是动态参数,排除匹配index和add为arg参数,并匹配到行末
路由地址和参数:
模块内部地址: c/a?arg1=val1&arg=val , array('c/a','arg1=val1&arg=:1'),array('c/a',array('arg'=>'val'))
外部地址(/或http开头): '/tp/admin/index/f?arg=:1' , array('http://m.tp.cn/home/:1','301');默认跳转码是301
闭包函数: function(arg1,arg2){};参数匹配在正则路由表达式按子模式顺序,在规则表示中按:arg1
*静态路由映射,定义在URL_MAP_RULES中,完全匹配(不含后缀名),不含动态参数
注: 内部地址路由,相当于请求转发器,外部地址路由相当于响应重定向
伪静态后缀名: URL_DENY_SUFFIX=>'jpg|gif|png|js|css' , URL_HTML_SUFFIX=>"html|xml|js",前者为拒绝访问的后缀,后者为允许访问的后缀,且此时.js文件不可访问
如果 'URL_HTML_SUFFIX'=>'',则支持所有后缀,可通过__EXT__记录的伪静态后缀进行有选择的响应
代码回忆录:ThinkPHP随笔-基于ThinkPHP3.2.3
猜你喜欢
转载自blog.csdn.net/Fantastic_/article/details/73481007
今日推荐
周排行