ThinkPHP教程_PHP框架之ThinkPHP(七)【create方法与令牌】
一、create()方法
create()方法用于创建数据对象,创建成功返回一个数组,失败返回一个false。因为在进行数据库操作(CRUD)之前,需要手动创建需要的数据。但是create()方法所做的工作并非只是创建一个数据对象那么简单!
create()可以自动根据POST传递过来的数据创建数据对象,特别强调一下,必须得是POST方式传递过来的,其它方式不行,测试如下
method为空,则默认是get方式
method为post
在测试中发现了一个问题,就是如果表单控件的名称不在模型中数据表字段中,则create()方法是不会创建它的
User这个模型类中数据表字段如下
如果将密码框的名称改成pwd,则create()方法不会创建之,因为在User模型中找不到与之相同的数据表字段名称
倘若将密码框的名称改成id,则结果如下
至于为啥可以直接在动作中去访问$_POST,是因为它是一个超全局变量
1、create()创建数据对象的方式有几种
·自动创建
即自动根据$_POST这个超全局变量创建数据对象,直接$Model->create()即可
·根据其它数组创建
ps,同样的道理,关联数组的键必须在User模型中有与之相同的数据表字段名
·根据其它模型对象创建
2、create()方法不只是创建数据对象,还完成了很多其它的工作,比如说令牌验证、自动映射、自动填充、自动验证等等!那么如果只想简单的创建一个数据对象,即并不需要完成其它一些复杂的功能,可以是使用data()方法
create()方法创建的数据对象是保存在内存中的,并没有写入到数据库中,要想写入数据库,还得通过add()或save()方法
注意,使用data()方法创建数据对象是不会进行自动验证和自动过滤的,可以手动处理。但是在进行add()或save()操作的时候,数据表中不存在的字段以及非法的数据类型(例如对象、数组等非标量数据)是会自动过滤的,所以不用担心非数据表字段的写入导致SQL错误!测试如下
说明,data()方法返回的是模型对象,并不像create()方法那样返回一个数组
可以看出在执行add()操作后,pwd并没有插入到数据库中,说明是被过滤掉了的
还有一点要注意,使用data()方法,是无法像create()那样自动根据$_POST来创建数据对象的,必须得手动将$_POST传入才行!测试如下
二、令牌验证
表单令牌验证功能,可以为表单的远程提交提供保护
1、相关配置
所谓表单验证,就是每次display操作时,ThinkPHP会自动在含有表单的模板中生成一个name为TOKEN_NAME、value为md5随机加密的值的隐藏域,并将这个md5随机加密值写入session中,服务器端在接收表单中的数据之前想通过将隐藏域传递过来value与session中的相关值进行比对,如果合法,则接收,否则不接受!
设想这样一种情形,如果某个用户非法将一个网站的表单提交页面copy到本地,然后在本地模拟恶意表单数据进行提交,那么该怎么防止?
有人可能会想到通过判断上级来源(即通过$_SERVER['HTTP_REFERER']判断),如果上级来源是本网站,则接收,否则不接收!但是可恨的是上级来源也可以被模拟
对于这种问题,ThinkPHP的令牌验证功能就能很好防止
特别强调一下,在每次display操作时都会生成新的令牌值,对于同步操作,提交表单后就跳转了,原先的表单模板页面也就是没了,那么如果想再回到表单模板页面,则需要服务display()一下,那么令牌值也就是更新了(但是,浏览器把表单模板页面缓存了这么办?---》解决方案,不让浏览器缓存,可以采用post方式或者在服务器端header("Cache-Control:no-cache");)!可是,如果是通过AJAX异步操作呢?且不说令牌更新问题,就连怎么把令牌传过去现在看来也成问题?
实际上,在服务器端对于每一个令牌值,只要验证过一次就会失效,所以即使你通过缓存页面再次发送了令牌,也是无法验证成功的!
2、{__TOKEN__}与{__NOTOKEN}
·{__TOKEN__}用于控制令牌隐藏域的位置,默认是在</form>之前
·{__NOTOKEN__}用于控制表单是否添加令牌隐藏域,即在开启令牌验证的情况下,如果希望个别表单模板不需要令牌验证功能,可以在该模板中加入{__NOTOKEN__}
·如果页面中存在多个表单,建议添加{__TOKEN__}表示
3、令牌验证分为两种
·create()方法的自动令牌验证,create()方法内置令牌验证功能
·调用模型的autoCheckToken()方法进行手工令牌验证,验证通过返回true,否则返回false。一般在使用data()方法创建数据对象时需要手工令牌验证,因为data()方法中没有进行令牌验证
posted on 2016-08-29 15:04 Yang24556 阅读(1696) 评论(0) 编辑 收藏 举报