PHP数据库类
简单封装PHP操作MySQL的类
<?php /* 类的名称:Model 类的作用:连接数据库执行sql语句 作 者:lim 更新时间:20170812 */ class Model{ //存放连接数据库的资源 private $link; //构造连接数据库 public function __construct(){ $link = mysqli_connect(HOST,USER,PWD,DBNAME) or die('数据库连接失败'); $this->link = $link; mysqli_set_charset($this->link,'utf8'); } /* 函数名称:query() 函数作用:处理查询 参 数:$sql: 提交的sql语句 返 回 值:返回一个二维数组 */ public function query($sql){ //过滤sql $sql=$this->CheckSql($sql); $res = mysqli_query($this->link,$sql); $list = array(); if($res){ while($row=mysqli_fetch_assoc($res)){ $list[] = $row; } return $list; } return "sql语句出错=> {$sql} "; } /* 函数名称:execute() 函数作用:处理增删改 参 数:$sql: 提交的sql语句 返 回 值:如果是添加返回id 如果是删除和修改返回影响行数 */ public function execute($sql){ //过滤sql $sql=$this->CheckSql($sql,"addupddel"); $res = mysqli_query($this->link,$sql); if($res){ return (mysqli_insert_id($this->link))?mysqli_insert_id($this->link):mysqli_affected_rows($this->link); } return "sql语句出错=> {$sql} "; } /* 函数名称:CheckSql() 函数作用:SQL语句过滤程序,由80sec提供,这里作了适当的修改 参 数:$sql: 处理的sql语句 参 数:$querytype: 类型 返 回 值:返回处理后的sql语句 */ private function CheckSql($sql, $querytype='select') { $clean = ''; $error = ''; $pos = -1; $old_pos = 0; //如果是普通查询语句,直接过滤一些特殊语法 if($querytype == 'select') { if(preg_match('/[^0-9a-z@\._-]{1,}(union|sleep|benchmark|load_file|outfile)[^0-9a-z@\.-]{1,}/', $sql)) { die('sql非法!'); } } //完整的SQL检查 while(true) { $pos = strpos($sql, '\'', $pos + 1); if($pos === false) { break; } $clean .= substr($sql, $old_pos, $pos - $old_pos); while(true) { $pos1 = strpos($sql, '\'', $pos + 1); $pos2 = strpos($sql, '\\', $pos + 1); if($pos1 === false) { break; } else if($pos2 == false || $pos2 > $pos1) { $pos = $pos1; break; } $pos = $pos2 + 1; } $clean .= '$s$'; $old_pos = $pos + 1; } $clean .= substr($sql, $old_pos); $clean = trim(strtolower(preg_replace(array('~\s+~s' ), array(' '), $clean))); //老版本的Mysql并不支持union,常用的程序里也不使用union,但是一些黑客使用它,所以检查它 if(strpos($clean, 'union') !== false && preg_match('~(^|[^a-z])union($|[^[a-z])~s', $clean) != 0) { $fail = true; $error = 'union detect'; } //发布版本的程序可能比较少包括--,#这样的注释,但是黑客经常使用它们 else if(strpos($clean, '/*') > 2 || strpos($clean, '--') !== false || strpos($clean, '#') !== false) { $fail = true; $error = 'comment detect'; } //这些函数不会被使用,但是黑客会用它来操作文件,down掉数据库 else if(strpos($clean, 'sleep') !== false && preg_match('~(^|[^a-z])sleep($|[^[a-z])~s', $clean) != 0) { $fail = true; $error = 'slown down detect'; } else if(strpos($clean, 'benchmark') !== false && preg_match('~(^|[^a-z])benchmark($|[^[a-z])~s', $clean) != 0) { $fail = true; $error = 'slown down detect'; } else if(strpos($clean, 'load_file') !== false && preg_match('~(^|[^a-z])load_file($|[^[a-z])~s', $clean) != 0) { $fail = true; $error = 'file fun detect'; } else if(strpos($clean, 'into outfile') !== false && preg_match('~(^|[^a-z])into\s+outfile($|[^[a-z])~s', $clean) != 0) { $fail = true; $error = 'file fun detect'; } //老版本的MYSQL不支持子查询,我们的程序里可能也用得少,但是黑客可以使用它来查询数据库敏感信息 else if(preg_match('~\([^)]*?select~s', $clean) != 0) { $fail = true; $error = 'sub select detect'; } if(!empty($fail)) { die('sql非法!!'); } else { return $sql; } } }