ThinkPHP框架安全实现分析(4)

可以看到,在parseSql中用正则表达式拼接了sql语句,但并没有直接的去处理各种插叙你的数据格式,而是在解析变量的过程中调用了多个函数,此处拿parseWhere举例子。

protected function parseWhere($where) { $whereStr = ''; if(is_string($where)) { // 直接使用字符串条件 $whereStr = $where; } else{ // 使用数组表达式 /*设定逻辑规则,如or and xor等,默认为and,此处省略*/ $operate=' AND '; /*解析特殊格式的表达式并且格式化输出*/ foreach ($where as $key=>$val){ if(0===strpos($key,'_')) { // 解析特殊条件表达式 $whereStr .= $this->parseThinkWhere($key,$val); } else{ // 查询字段的安全过滤 $multi = is_array($val) && isset($val['_multi']); //判断是否有复合查询 $key = trim($key); /*处理字段中包含的| &逻辑*/ if(strpos($key,'|')) { // 支持 name|title|nickname 方式定义查询字段 /*将|换成or,并格式化输出,此处省略*/ } elseif(strpos($key,'&')){ /*将&换成and,并格式化输出,此处省略*/ } else{ $whereStr .= $this->parseWhereItem($this->parseKey($key),$val); } } $whereStr .= $operate; } $whereStr = substr($whereStr,0,-strlen($operate)); } return empty($whereStr)?'':' WHERE '.$whereStr; } // where子单元分析 protected function parseWhereItem($key,$val) { $whereStr = ''; if(is_array($val)){ if(is_string($val[0])){ $exp = strtolower($val[0]); //如果是$map['id']=array('eq',100)一类的结构,那么解析成数据库可执行格式 if(preg_match('/^(eq|neq|gt|egt|lt|elt)$/',$exp)){ $whereStr .= $key.' '.$this->exp[$exp].' '.$this->parseValue($val[1]); } //如果是模糊查找格式 elseif(preg_match('/^(notlike|like)$/',$exp)){// 模糊查找,$map['name']=array('like','thinkphp%'); if(is_array($val[1])) { //解析格式如下:$map['b'] =array('notlike',array('%thinkphp%','%tp'),'AND'); $likeLogic = isset($val[2])?strtoupper($val[2]):'OR'; //如果没有设定逻辑结构,则默认为OR if(in_array($likeLogic,array('AND','OR','XOR'))){ /* 根据逻辑结构,组合语句,此处省略*/ $whereStr .= '('.implode(' '.$likeLogic.' ',$like).')'; } } else{ $whereStr .= $key.' '.$this->exp[$exp].' '.$this->parseValue($val[1]); } }elseif('bind' == $exp ){ // 使用表达式,pdo数据绑定 $whereStr .= $key.' = :'.$val[1]; }elseif('exp' == $exp ){ // 使用表达式 $map['id'] = array('exp',' IN (1,3,8) '); $whereStr .= $key.' '.$val[1]; }elseif(preg_match('/^(notin|not in|in)$/',$exp)){ //IN运算 $map['id'] = array('not in','1,5,8'); if(isset($val[2]) && 'exp'==$val[2]){ $whereStr .= $key.' '.$this->exp[$exp].' '.$val[1]; }else{ if(is_string($val[1])) { $val[1] = explode(',',$val[1]); } $zone = implode(',',$this->parseValue($val[1])); $whereStr .= $key.' '.$this->exp[$exp].' ('.$zone.')'; } }elseif(preg_match('/^(notbetween|not between|between)$/',$exp)){ //BETWEEN运算 $data = is_string($val[1])? explode(',',$val[1]):$val[1]; $whereStr .= $key.' '.$this->exp[$exp].' '.$this->parseValue($data[0]).' AND '.$this->parseValue($data[1]); }else{ //否则抛出异常 E(L('_EXPRESS_ERROR_').':'.$val[0]); } } else{ //解析如:$map['status&score&title'] =array('1',array('gt','0'),'thinkphp','_multi'=>true); $count = count($val); $rule = isset($val[$count-1]) ? (is_array($val[$count-1]) ? strtoupper($val[$count-1][0]) : strtoupper($val[$count-1]) ) : '' ; if(in_array($rule,array('AND','OR','XOR'))){ $count = $count -1; }else{ $rule = 'AND'; } for($i=0;$i<$count;$i++){ $data = is_array($val[$i])?$val[$i][1]:$val[$i]; if('exp'==strtolower($val[$i][0])) { $whereStr .= $key.' '.$data.' '.$rule.' '; }else{ $whereStr .= $this->parseWhereItem($key,$val[$i]).' '.$rule.' '; } } $whereStr = '( '.substr($whereStr,0,-4).' )'; } } else { //对字符串类型字段采用模糊匹配 $likeFields = $this->config['db_like_fields']; if($likeFields && preg_match('/^('.$likeFields.')$/i',$key)) { $whereStr .= $key.' LIKE '.$this->parseValue('%'.$val.'%'); }else { $whereStr .= $key.' = '.$this->parseValue($val); } } return $whereStr; } protected function parseThinkWhere($key,$val) { //解析特殊格式的条件 $whereStr = ''; switch($key) { case '_string':$whereStr = $val;break; // 字符串模式查询条件 case '_complex':$whereStr = substr($this->parseWhere($val),6);break; // 复合查询条件 case '_query':// 字符串模式查询条件 /*处理逻辑结构,并且格式化输出字符串,此处省略*/ } return '( '.$whereStr.' )'; }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/3d5b9b34bafaabb81a3c3006c253aa5c.html