A-A+

thinkphp自动验证方法

2015年03月07日 thinkphp开发 暂无评论 阅读 129 次

上一篇文章思雨网络介绍了create()方法,这个是全部的自动验证方法详解.

ThinkPHP 自动验证 字段映射 自动完成

create方法将上述的三个功能整合到了一起,也就是说,任何一个验证出现差错,都不能返回希望得到的$data(可能是部分字段的数据)

首先自动验证是针对表单字段的,验证的条件包括

Model::EXISTS_VALIDATE 或者0 表单中存在需要验证的字段就验证 (默认)

Model::MUST_VALIDATE 或者1 必须验证 不管表单是否有设置该字段 (尚未发现何时能用到该项,比较奇怪)

Model::VALUE_VALIDATE或者2 表单中字段值不为空的时候验证

这里分这么几种情况

1 验证字段中($_validate)存在该字段验证信息,如array("username","require","用户名必须",0),而表单中也存 在一个字段(如username),此事即默认情况, 表单中存在需要验证的字段,验证通过后存入模型的$data成员属性中,验证失败则不存 入,$data直接设置为false,错误信息写入模型的$error成员属性中,方便程序员后续的查询。

2 验证字段中($_validate)不存在该字段验证信息,而验证字段中($_validate)不存在该字段验证信息,那么不验证,直接存到$data中

3 验证字段中($_validate)不存在该字段验证信息,而验证的条件Model::MUST_VALIDATE 或 1, 那么不管表单中又没有该字段(即为空),都验证。

4 验证字段中($_validate)存在该字段验证信息,Model::VALUE_VALIDATE或者2 表单中字段值不为空的时候验证。

当然如果数据库中没有表单中的字段,返回的$data数据也会过滤掉相应的字段。

if($this->autoCheckFields) { // 开启字段检测 则过滤非法字段数据
$fields =   $this->getDbFields();
foreach ($data as $key=>$val){
if(!in_array($key,$fields)) {
unset($data[$key]);
}elseif(MAGIC_QUOTES_GPC && is_string($val)){
$data[$key] =   stripslashes($val);
}
}
}
全部源码如下:
public function create($data='',$type='') {
// 如果没有传值默认取POST数据
if(empty($data)) {
$data   =   $_POST;
}elseif(is_object($data)){
$data   =   get_object_vars($data);
}
// 验证数据
if(empty($data) || !is_array($data)) {
$this->error = L('_DATA_TYPE_INVALID_');
return false;
}// 检查字段映射
$data = $this->parseFieldsMap($data,0);// 状态
$type = $type?$type:(!empty($data[$this->getPk()])?self::MODEL_UPDATE:self::MODEL_INSERT);

// 检测提交字段的合法性
if(isset($this->options['field'])) { // $this->field('field1,field2...')->create()
$fields =   $this->options['field'];
unset($this->options['field']);
}elseif($type == self::MODEL_INSERT && isset($this->insertFields)) {
$fields =   $this->insertFields;
}elseif($type == self::MODEL_UPDATE && isset($this->updateFields)) {
$fields =   $this->updateFields;
}
if(isset($fields)) {
if(is_string($fields)) {
$fields =   explode(',',$fields);
}
// 判断令牌验证字段
if(C('TOKEN_ON'))   $fields[] = C('TOKEN_NAME');
foreach ($data as $key=>$val){
if(!in_array($key,$fields)) {
unset($data[$key]);
}
}
}

// 数据自动验证
if(!$this->autoValidation($data,$type)) return false;

// 表单令牌验证
if(C('TOKEN_ON') && !$this->autoCheckToken($data)) {
$this->error = L('_TOKEN_ERROR_');
return false;
}

// 验证完成生成数据对象
if($this->autoCheckFields) { // 开启字段检测 则过滤非法字段数据
$fields =   $this->getDbFields();
foreach ($data as $key=>$val){
if(!in_array($key,$fields)) {
unset($data[$key]);
}elseif(MAGIC_QUOTES_GPC && is_string($val)){
$data[$key] =   stripslashes($val);
}
}
}

// 创建完成对数据进行自动处理
$this->autoOperation($data,$type);
// 赋值当前数据对象
$this->data =   $data;
// 返回创建的数据以供其他调用
return $data;
}

// 自动表单令牌验证
// TODO  ajax无刷新多次提交暂不能满足
public function autoCheckToken($data) {
if(C('TOKEN_ON')){
$name   = C('TOKEN_NAME');
if(!isset($data[$name]) || !isset($_SESSION[$name])) { // 令牌数据无效
return false;
}

// 令牌验证
list($key,$value)  =  explode('_',$data[$name]);
if($value && $_SESSION[$name][$key] === $value) { // 防止重复提交
unset($_SESSION[$name][$key]); // 验证完成销毁session
return true;
}
// 开启TOKEN重置
if(C('TOKEN_RESET')) unset($_SESSION[$name][$key]);
return false;
}
return true;
}

标签:

给我留言

Copyright © web前端技术开发个人博客 保留所有权利  京ICP备14060653号 Theme  Ality

用户登录