2017.1.28-2017.1.31
特征3:包含了一些优秀的设计模式
定义:框架是一堆包含了常量、方法和类等代码的集合,它是一个半成品的应用,只包含了一些项目开发时候所使用的低层框架,并包含业务逻辑,框架还包含了一些优秀设计模式。
MVC是一个设计模式。它强制将用户的输入、逻辑、输出相分离,将整个项目分为三个部分:控制器(C)、模型(M)、视图(V)
3.2.3
官网:http://www.thinkphp.cn/
解压后(完整版)
通过浏览器访问站点目录
结果:可以从浏览器看到一个(:,而且在站点目录下自动生成一个Application文件夹,目录结构如下图所示。
HOME文件结构:
命名规则:控制名(英文首字母大写)+Controller关键字+.class.php
普通形式路由(get形式路由)
路由形式:http://网址/入库文件?m=分组名&c=控制器名&a=方法名&参数名=参数值
pathindo路由形式(默认)
路由形式:http://网址/入口文件/分组名/控制器名/方法/参数名1/参数值1/参数名2/参数值2
rewrite路由形式(需配置)
路由形式与默认形式相比少了入口文件
兼容形式
路由形式:http://网址/入口文件?s=/分组名/控制器名/方法名/参数名1/参数值1
定义:一般项目会根据某个功能的使用对象来区分代码,这个时候放到一起之后会形成一个文件夹,这个文件夹就可以称之为分组。分组就是我们通常所指的平台(前台、后台)
例如在刚部署好的thinkPHP系统中home目录就是一个分组目录。后期如果需要使用更多的分组,则需要自己去创建分组。
步骤:参考home分组,重新创建一个新的目录,在其中依照home中的结构,创建相应的目录即可。
语法格式:U("URL路径",参数数组)
例如:
访问当前控制器下的index方法,可使用U("index");
访问Index控制器下的index方法,则用U("Index/index");
当然也可以指定分组和传递参数
成功跳转
$this->success(跳转提示,跳转地址,等待时间);
失败跳转
$this->error(跳转提示,跳转地址,等待时间);
跳转提示参数必须要有,后面的地址和时间可以没有,如果没有指定跳转地址,则跳转到上一页
创建的位置需要在分组目录下的View目录下与控制器同名的目录中。
例如Test控制器中的login方法,需要一个模板,则该模板文件login.html需要放到View/Test/login.html
$this->display(); //展示当前控制器下与当前请求方法名称一致的模板文件
$this->dispaly('模板文件名[不带后缀]'); //展示当前控制器下的指定模板文件
$this->display('View目录下的目录名/模板文件名[不带后缀]'); //展示指定控制器目录下的指定模板文件
__MODULE__:表示从域名后面开始一直到分组名结束的路由
__CONTROLLER__:表示从域名后面开始一直到控制器名结束的路由
__ACTION__:表示从域名后面开始一直到方法名结束的路由
__PUBLIC__:站点根目录下的Public目录的路由
__SELF__:表示从域名后面开始一直到路由的最后(如果没有参数,则__SELF__和__ACTION__所表达的内容是一样的)
在当前分组的Conf/config.php中配置
$this->display(); //展示模板
$this->fetch(); //获取模板(有返回值)
普通的html注释
thinkPHP中的行注释
{//注释内容}
thinkPHP中的块注释
{/*块注释内容*/}
普通的html注释属于客户端注释,会在浏览器的源码中输出;而thinkPHP的注释属于服务端注释,不会被浏览器输出
中括号形式
{$array[key]}
点形式
{$array.key}
箭头形式
{$o->id}
冒号形式
{$o:id}
注意没有点形式
为了在后期使用中文的时候不乱码,可以在入口文件(index.php)中添加一个header声明
header('Content-Type:text/html;charset=utf8');
语法格式:{$变量|函数名1|函数名2=参数1,参数2...}
参数说明:
$变量:模板变量
函数名1:第一个函数
函数名2:第二个函数
参数1、参数2:函数2的参数
=:表示该函数有参数
###:变量本身
例子:格式化时间戳
{$time|date='Y-m-d H:i:s',###}
例子:截取前5个字符,并将其转化为大写
{$str|substr=0,5|strtoupper}
例子:默认
{$str=default='这是一个默认值'}
语法格式:
也可以传递参数
接收:[a]
Volist
语法格式:
//循环体
foreach
语法格式:
//循环体
可以说foreach是volist的一个简化版
语法格式:
//操作
//操作
......
//最后一个操作
'DB_TYPE' => 'mysql', // 数据库类型
'DB_HOST' => 'localhost', // 服务器地址
'DB_NAME' => 'user', // 数据库名
'DB_USER' => 'root', // 用户名
'DB_PWD' => '951029', // 密码
'DB_PORT' => '3306', // 端口
'DB_PREFIX' => '', // 数据库表前缀
命名规范:模型名(不带前缀的表名并且首字母大写)+Model关键字+class.php
第一步:声明命名空间
第二步:引入父类模型Model.class.php
第三步:声明模型并且继承父类模型
public function model(){
$model=new \Home\Model\UserModel();
dump($model);
}
D方法
$obj=D(['模型名']);
作用:实例化自己创建的模型(分组/Model目录中),如果制定了表名,则实例化指定的模型,如果没有指定或者模型名不存在,则直接实例化父类模型(Model.class.php)
M方法
$obj=M(['不带前缀的表名']);
作用:直接实例化父类模型(Think目录下的Model.class.php);如果制定了表名,则实例化父类模型的时候关联指定的表;如果没有指定表名则不关联表,一般用于执行原生的sql语句
D方法实例化自定义模型,如果自定义模型不存在,在实例化父类模型;M方法是实例化父类模型。两者的差异就是实例化对象不一样。
如果父类中的方法不能满足我们的开发需求,需要自己定义方法
语法格式:$model->add(一维数组); //返回添加的信息的id
要求:一维数组必须是关联数组
$model=M("User");
$data=array('name' =>'zcw' ,'pass'=>666 );
$result=$model->add($data);
dump($result);
如果要增加多条数据:(1)循环使用add方法(2)addAll(二维数组)
要求:最里面的那层数组是关联数组,外层数组必须是下标从0开始的连续索引数组
语法格式:$model->save(一维关联数组);
一维数组中一定要有主键信息。返回值为影响的行数
$model->find(id); //查询指定id的信息
select方法返回的是一个二维数组;find返回值是一维数组
在分组的配置文件中写配置项:
'SHOW_PAGE_TRACE' => true
生产模式:是指项目上线的时候所使用的模式,错误信息比较模糊
在入口文件(index.php)中配置
define('APP_DEBUG',true); //true表示开启调试模式
$model->getLastSql(); 获得当前模型中最后一条执行成功的SQL语句
别名方法$model->_sql()
G方法可以用来测试一段代码的执行时间:
G('开始标记')
//测试的代码
.....
G('结束标记');
G('开始标记','结束标记',数字/字符m)
第三个参数:如果为数字则表示统计执行时间,数字标识精确的小数位数,单位秒;如果是字符m,则表示统计内存开销,单位是byt,需要服务器支持
AR模式即Active Record模式,是一个对象关系映射技术。
AR模式的核心:三个映射/对应
AR类 === 表
AR类的属性=== 表的字段
AR类实例 === 表的记录
$model=M('user');
$model->name='test';
$model->pass="666";
$result=$model->add();
dump($result);
$model=M('user');
$model->id=9;
$model->name='tttt';
$model->pass="666";
$result=$model->save();
$model=M('user');
$model->id='7,8,9';
$result=$model->delete();
dump($result);
group 表示按照指定的字段进行分组查询
可将辅助方法全部写在一行上,只要CURD方法在最后即可。
sum() 表示求出某个字段的总和
$count=$model->count();
$max=$model->max("字段名");
$min=$model->min("字段名");
$avg=$model->avg("字段名");
$sum=$model->sum("字段名");
前面介绍的sql调试方法getLastSql或者别名_sql(),都要求最后一条成功执行SQL语句,只能用来调试逻辑错误,并不能拿来调试语法错误。
fetchSql方法使用的时候可以完全看做是一个辅助方法,所以要求必须在model之后,在CURD操作之前,顺序无所谓。只能在thinkPHP3.2.3版本之后。
例子:
$result=$model->fetchSql(true)->delete(); //$result是一条删除的SQL语句,并且并未执行而是返回了SQL语句而已。
数据对象也就是父类模型中的$this->data,thinkPHP系统中提供另外一种批量设置数据对象的方法:create方法
语法结构:$model->create();
如果不给create方法传递参数,则其默认使用post中的数据。
例子:
$model->create();
$result=$model->add();
在自定义模板中配置$_validate属性,配置如下:
protected $_validate =array(
//针对name的规则:必填、不可重复
array('name','require','name必填!'),
array('name','','name已存在!',0,'unique'),
//验证pass是否为数字
array('pass','number','必须为数字'),
);
自动验证失败,则create方法返回false,成功则返回正常的数组。
控制器获取验证失败信息,首先得用D()方法来实例化模型:
$this->error($model->getError());exit;
用户体验不是很好,大部分是用js代码解决。
在自定义的模型中:
protected $patchValidate=true;
目的:为了防止别人猜出自己的表结构
规则:
成员属性:$_map=array();
实例(自定义控制器中修改):
protected $_map=array(
//键是表单中的name值 = 值是数据表中的字段名
'abc' => 'id'
);
注意:必须使用数据对象的创建方法接受数据。
有时候系统会默认给我们添加上之前在配置文件中定义的表前缀,所以有时候“name”表就会变成前缀+“name”表
所以可以在自定义的模型类加上$trueTableName属性:
protected $trueTableName='name';
cookie(null): 清空所有的cookie,但是有bug
修改ThinkPHP/Common/functions.php第1377、1379行
//配置
$cfg=array(
'useImgBg' => false, // 使用背景图片
'fontSize' => 25, // 验证码字体大小(px)
'useCurve' => true, // 是否画混淆曲线
'useNoise' => true, // 是否添加杂点
'imageH' => 0, // 验证码图片高度
);
//实例化验证码类
$verify=new \Think\Verify($cfg);
//输出验证码
$verify->entry();
(可选步骤)定制显示分页提示文字
设置首页和末页的时候需要注意,如果总的页码数小于分页类中rollPage属性,则不会显示首页和末页的按钮,这时候需要修改rollPage的值;由于分页类中lastSuffix属性,定义最后一页总页数,所以将其改为false
$page->rollPage=5;
$page->lastSuffix=false;
输出模板
//模板实例化
$model=M("user");
//第一步:查询总的记录数
$count=$model->count();
//第二步:实例化分类页,传递参数,每页显示1个
$page=new \Think\Page($count,1);
//第三步:可选步骤,定义提示文字
$page->setConfig('prev','上一页');
$page->setConfig('next','下一页');
$page->setConfig('last','末页');
$page->setConfig('first','首页');
//使用show方法生成URL
$show=$page->show();
//展示数据
$data=$model->limit($page->firstRow,$page->listRows)->select();
//传递给模板
$this->assign('data',$data);
$this->assign('show',$show);
//展示模板
$this->display();
在模板中指定容器的位置