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()方法中没有进行令牌验证

原文地址:https://www.cnblogs.com/TigerYangWTH/p/5818026.html