【PHP】ThinkPHP的用法记录(TP3.2.3)

PHP 专栏收录该内容
3 篇文章 0 订阅
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__记录的伪静态后缀进行有选择的响应
		
		
			

 

  • 0
    点赞
  • 0
    评论
  • 1
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页

打赏作者

chavinchen

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值