首页 > 代码库 > PHP数据库类

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;
        }
    } 
    
    
    
}

 

PHP数据库类