thinkphp 三大自动验证
1 public function create($data='',$type='') { 2 // 如果没有传值默认取POST数据 3 if(empty($data)) { 4 $data = $_POST; 5 }elseif(is_object($data)){ 6 $data = get_object_vars($data); 7 } 8 // 验证数据 9 if(empty($data) || !is_array($data)) { 10 $this->error = L('_DATA_TYPE_INVALID_'); 11 return false; 12 } 13 14 // 检查字段映射 15 $data = $this->parseFieldsMap($data,0); 16 17 // 状态 18 $type = $type?$type:(!empty($data[$this->getPk()])?self::MODEL_UPDATE:self::MODEL_INSERT); 19 20 // 检测提交字段的合法性 21 if(isset($this->options['field'])) { // $this->field('field1,field2...')->create() 22 $fields = $this->options['field']; 23 unset($this->options['field']); 24 }elseif($type == self::MODEL_INSERT && isset($this->insertFields)) { 25 $fields = $this->insertFields; 26 }elseif($type == self::MODEL_UPDATE && isset($this->updateFields)) { 27 $fields = $this->updateFields; 28 } 29 if(isset($fields)) { 30 if(is_string($fields)) { 31 $fields = explode(',',$fields); 32 } 33 // 判断令牌验证字段 34 if(C('TOKEN_ON')) $fields[] = C('TOKEN_NAME'); 35 foreach ($data as $key=>$val){ 36 if(!in_array($key,$fields)) { 37 unset($data[$key]); 38 } 39 } 40 } 41 42 // 数据自动验证 43 if(!$this->autoValidation($data,$type)) return false; 44 45 // 表单令牌验证 46 if(C('TOKEN_ON') && !$this->autoCheckToken($data)) { 47 $this->error = L('_TOKEN_ERROR_'); 48 return false; 49 } 50 51 // 验证完成生成数据对象 52 if($this->autoCheckFields) { // 开启字段检测 则过滤非法字段数据 53 $fields = $this->getDbFields(); 54 foreach ($data as $key=>$val){ 55 if(!in_array($key,$fields)) { 56 unset($data[$key]); 57 }elseif(MAGIC_QUOTES_GPC && is_string($val)){ 58 $data[$key] = stripslashes($val); 59 } 60 } 61 } 62 63 // 创建完成对数据进行自动处理 64 $this->autoOperation($data,$type); 65 // 赋值当前数据对象 66 $this->data = $data; 67 // 返回创建的数据以供其他调用 68 return $data; 69 } 70 71 // 自动表单令牌验证 72 // TODO ajax无刷新多次提交暂不能满足 73 public function autoCheckToken($data) { 74 if(C('TOKEN_ON')){ 75 $name = C('TOKEN_NAME'); 76 if(!isset($data[$name]) || !isset($_SESSION[$name])) { // 令牌数据无效 77 return false; 78 } 79 80 // 令牌验证 81 list($key,$value) = explode('_',$data[$name]); 82 if($value && $_SESSION[$name][$key] === $value) { // 防止重复提交 83 unset($_SESSION[$name][$key]); // 验证完成销毁session 84 return true; 85 } 86 // 开启TOKEN重置 87 if(C('TOKEN_RESET')) unset($_SESSION[$name][$key]); 88 return false; 89 } 90 return true; 91 }
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) { // 开启字段检测 则过滤非法字段数据 53 $fields = $this->getDbFields(); 54 foreach ($data as $key=>$val){ 55 if(!in_array($key,$fields)) { 56 unset($data[$key]); 57 }elseif(MAGIC_QUOTES_GPC && is_string($val)){ 58 $data[$key] = stripslashes($val); 59 } 60 } 61 }
未完待续