Skip to content

Latest commit

 

History

History
471 lines (420 loc) · 18.6 KB

README.md

File metadata and controls

471 lines (420 loc) · 18.6 KB

PDO数据库的封装类


PHP连接数据库的方式主要有mysql、mysqli、pdo三种 mysql由于安全行性的原因在php5.5就被官方弃用 这里不再多说 而mysqli和pdo两者都各有优点 这里我们将两者简单对比一下 并封装了一个可以满足日常使用的pdo类

首先

。。。。算了 介绍有空再写吧。。。

<?php

/****************************************************
 * Author Howard.
 * Date: 2017/11/9
 * Version 1.0
 * 支持SELECT/UPDATE/INSERT命令的预处理及
 * SELETE/UPDATE/INSERT/DELETE命令的直接执行
 * 在WHERE子句中 仅可使用“=”操作符 其他操作符请自行构造sql语句
 ****************************************************/
class DateBase
{

    public  $pdo = null;
    private $dbType = "mysql";    //数据库类型
    private $dbPort = "3306";     //数据库端口号
    private $dbHost;              //数据库主机
    private $dbName;              //数据库名
    private $userName;            //用户名
    private $password;            //用户密码
    public  $debug = true;        //调试模式
    private $prepare;

    public function __construct($dbHost, $dbName, $userName, $password)
    {
        $this->dbHost = $dbHost;
        $this->dbName = $dbName;
        $this->userName = $userName;
        $this->password = $password;
        $this->dbConnect();
    }

    private function dbConnect()
    {
        try {
            $dbr = $this->dbType . ':host=' . $this->dbHost . ';port=' . $this->dbPort . ';dbname=' . $this->dbName;
            $this->pdo = new PDO($dbr, $this->userName, $this->password, array(PDO::ATTR_PERSISTENT => true));          //设置为长连接
            $this->pdo->exec('SET NAMES utf8');
            $this->pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);                                 //关闭本地预处理
            $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);                           //错误模式,此项为警告模式
//            $this->pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);                                       //错误模式,此项为异常模式
        } catch (PDOException $e) {
            die('Connection failed: ' . $e->getMessage());
        }
    }


    /* *
     * 普通的SELECT语句
     * 使用PDO::query方法
     * @param  string   $table      数据表名称
     * @param  array    $fields     选择的列名称 空值时为返回所有
     * @param  array    $where      where条件 仅支持“=”作为判断操作符 键名为字段名 键值为对应值
     * @param  string   $orderby    指定列排序
     * @param  boolean  $sort       降序/升序排列  默认为升序 false为降序
     * @param  string   $limit      限制返回结果数量及起始位置 单参数时为返回值数量 双参数时为起始位置和数量
     * @param  string   $fetch      返回数组关联方式 默认为FETCH_BOTH assoc为FETCH_ASSOC num时为FETCH_NUM both时为FETCH_BOTH
     * @return array                返回查询结果数组
     * */
    public function select($table, $fields = "", $where = "", $orderby = "", $sort = true, $limit = "", $fetch = "both")
    {
        $sql = $this->sqlCreat("select", array("table" => $table, "fields" => $fields, "where" => $where, "orderby" => $orderby, "sort" => $sort, "limit" => $limit));
        if ($this->debug) {
            print_r($sql);
        }
        $res = $this->selectExec($sql, $fetch);
        return $res;
    }


    /* *
     * 使用预处理的SELECT语句
     * 内部使用PDO的prepare预处理 并自动绑定参数 防止注入
     * @param  string   $table      数据表名称
     * @param  array    $fields     选择的列名称 空值时为返回所有
     * @param  array    $where      where条件 仅支持“=”作为判断操作符 键名为字段名 键值为对应值
     * @param  string   $orderby    指定列排序
     * @param  boolean  $sort       降序/升序排列  默认为升序 false为降序
     * @param  string   $limit      限制返回结果数量及起始位置 单参数时为返回值数量 双参数时为起始位置和数量
     * @param  string   $fetch      返回数组关联方式 默认为FETCH_BOTH assoc为FETCH_ASSOC num时为FETCH_NUM both时为FETCH_BOTH
     * @return array                返回查询结果数组
     * */
    public function select_($table, $fields = "", $where = "", $orderby = "", $sort = true, $limit = "", $fetch = "both")
    {
        $sql = $this->sqlCreat("select_", array("table" => $table, "fields" => $fields, "where" => $where, "orderby" => $orderby, "sort" => $sort, "limit" => $limit));
        if ($this->debug) {
            print_r($sql);
        }
        $res = $this->select_Exec($sql, $where, $fetch);
        return $res;
    }


    /* *
     * 普通的INSERT语句
     * 使用PDOStatement::exec方法
     * @param string $table 数据表名
     * @param array  $data  键名为列名 键值为插入值
     * @return int          返回受影响记录数
     * */
    public function insert($table, $data)
    {
        $sql = $this->sqlCreat("insert", array("table" => $table, "data" => $data));
        if ($this->debug) {
            print_r($sql);
        }
        $res = $this->normalExec($sql);

        return $res;
    }


    /* *
     * 使用预处理的INSERT语句
     * 内部使用PDO的prepare预处理 并自动绑定参数 防止注入
     * @param string $table     数据表名
     * @param array  $data      键名为列名 键值为插入值
     * @return int              返回受影响记录数
     * */
    public function insert_($table, $data)
    {
        $sql = $this->sqlCreat("insert_", array("table" => $table, "data" => $data));
        if ($this->debug) {
            print_r($sql);
        }
        $res = $this->insert_Exec($sql, $data);
        return $res;
    }


    /*
     * 普通的UPDATE语句
     * 使用PDO::exec方法
     * @param  string   $table      数据表名称
     * @param  array    $data       键名为列名 键值为要更改值
     * @param  array    $where      where条件 仅支持“=”作为判断操作符 键名为字段名 键值为对应值
     * @return int                  返回影响数目
     * */
    public function update($table, $data, $where = "")
    {
        $sql = $this->sqlCreat("update", array("table" => $table, "data" => $data, "where" => $where));
        if ($this->debug) {
            print_r($sql);
        }
        $res = $this->normalExec($sql);
        return $res;
    }


    /* *
     * 使用预处理的UPDATE语句
     * 内部使用PDO的prepare预处理 并自动绑定参数 防止注入
     * @param  string   $table      数据表名称
     * @param  array    $fields     选择的列名称 空值时为返回所有
     * @param  array    $where      where条件 仅支持“=”作为判断操作符 键名为字段名 键值为对应值
     * @param  string   $orderby    指定列排序
     * @param  boolean  $sort       降序/升序排列  默认为升序 false为降序
     * @param  string   $limit      限制返回结果数量及起始位置 单参数时为返回值数量 双参数时为起始位置和数量
     * @param  string   $fetch      返回数组关联方式 默认为FETCH_BOTH assoc为FETCH_ASSOC num时为FETCH_NUM both时为FETCH_BOTH
     * @return array                返回查询结果数组
     * */
    public function update_($table, $data, $where = "")
    {
        $sql = $this->sqlCreat("update_", array("table" => $table, "data" => $data, "where" => $where));
        if ($this->debug) {
            print_r($sql);
        }
        $res = $this->update_Exec($sql, $data, $where);
        return $res;
    }


    /*
     * 普通的DELETE语句
     * 使用PDO::exec方法
     * @param  string   $table      数据表名称
     * @param  array    $data       键名为列名 键值为要更改值
     * @param  array    $where      where条件 仅支持“=”作为判断操作符 键名为字段名 键值为对应值
     * @return int                  返回影响数目
     * */
    public function delete($table, $where = "")
    {
        $sql = $this->sqlCreat("delete", array("table" => $table, "where" => $where));
        if ($this->debug) {
            print_r($sql);
        }
        $res = $this->normalExec($sql);
        return $res;
    }


    /* *
     * sql语句构造方法
     * SELECT时默认升序
     * @param  string  $command   命令标志符 用于判断执行的命令类型
     * @param  array   $paramArr  命令参数
     * @return sting              返回组装好的sql语句
     *
     * */
    private function sqlCreat($command, $paramArr)
    {
        switch ($command) {
            case "select_":
                $fildsSql = empty($paramArr["filds"]) ? "*" : implode(",", $paramArr["filds"]);
                $whereSql = empty($paramArr["where"]) ? "1=1" : $this->whereCreat(true, $paramArr["where"]);
                $limitSql = empty($paramArr["limit"]) ? "" : " LIMIT " . $paramArr["limit"];
                $sort = $paramArr["sort"] ? " ASC" : " DESC";
                $orderbySql = empty($paramArr["orderby"]) ? "" : " ORDER BY " . $paramArr["orderby"] . $sort;
                $sql = "SELECT " . $fildsSql . " FROM " . $paramArr["table"] . " WHERE " . $whereSql . $orderbySql . $limitSql;
                break;
            case "select":
                $fildsSql = empty($paramArr["filds"]) ? "*" : implode(",", $paramArr["filds"]);
                $whereSql = empty($paramArr["where"]) ? "1=1" : $this->whereCreat(false, $paramArr["where"]);
                $limitSql = empty($paramArr["limit"]) ? "" : " LIMIT " . $paramArr["limit"];
                $sort = $paramArr["sort"] ? " ASC" : " DESC";
                $orderbySql = empty($paramArr["orderby"]) ? "" : " ORDER BY " . $paramArr["orderby"] . $sort;
                $sql = "SELECT " . $fildsSql . " FROM " . $paramArr["table"] . " WHERE " . $whereSql . $orderbySql . $limitSql;
                break;
            case "insert":
                $arrKey = array_keys($paramArr["data"]);
                $key = implode(",", $arrKey);
                $val = "'" . implode("','", $paramArr["data"]) . "'";
                $sql = "INSERT INTO " . $paramArr["table"] . " (" . $key . ") VALUES (" . $val . ")";
                break;
            case "insert_":
                $arrKey = array_keys($paramArr["data"]);
                $key = implode(",", $arrKey);
                $val = ":" . implode(",:", $arrKey);
                $sql = "INSERT INTO " . $paramArr["table"] . " (" . $key . ") VALUES (" . $val . ")";
                break;
            case "update":
                $dataSql = $this->updateSqlCreat("dataEqual", $paramArr["data"]);
                $whereSql = empty($paramArr["where"]) ? "1=1" : $this->whereCreat(false, $paramArr["where"]);
                $sql = "UPDATE " . $paramArr["table"] . " SET " . $dataSql . " WHERE " . $whereSql;
                break;
            case "update_":
                $dataSql = $this->updateSqlCreat("dataQuest", $paramArr["data"]);
                $whereSql = empty($paramArr["where"]) ? "1=1" : $this->updateSqlCreat("whereQuest", $paramArr["where"]);
                $sql = "UPDATE " . $paramArr["table"] . " SET " . $dataSql . " WHERE " . $whereSql;
                break;
            case "delete":
                $whereSql = empty($paramArr["where"]) ? "1=1" : $this->whereCreat(false, $paramArr["where"]);
                $sql = "DELETE FROM " . $paramArr["table"] . " WHERE " . $whereSql;
                break;
        }
        return $sql;
    }


    /* *
     * 构造WHERE子句的方法
     * @param  string $conlon    标记是否需要绑定参数 需要绑定参数时 构造的where子句中为带有冒号的变量形式 否则为无冒号的对应的值
     * @param  array  $array     WHERE子句的列名和变量名一般分别对应本数组的键名和键值
     * @return string            构造好的WHERE子句
     * */
    private function whereCreat($conlon, $array)
    {
        $res = "";
        if ($conlon) {
            foreach ($array as $key => $value) {
                $res .= $key . " = :" . $key . " AND ";
            }
        } else if (!$conlon) {
            foreach ($array as $key => $value) {
                $res .= $key . " = '" . $value . "' AND ";
            }
        }
        $res = $res . "1=1";
        return $res;
    }


    /* *
     * 由于UPDATE命令的语句格式较为特殊 有两处需要构造因此此命令的构造单独使用一个方法
     * @param  string $command  标记是何处以及何种方式的构造  dataEqual为无需绑定参数时构造UPDATE的列名和新值
     *                          dataQuest为需要绑定参数时的列名和新值 whereQuest为WHERE子句的构造 需绑定参数
     * @param  array  $arr      构造时的数组 列名和变量名一般分别对应本数组的键名和键值
     * @return string           构造好的子句
     * */
    private function updateSqlCreat($command, $arr)
    {
        if ($command == "dataEqual") {
            foreach ($arr as $key => $value) {
                $resArr[] = $key . " = " . $value;
            }
            $res = implode(",", $resArr);
        } else if ($command == "dataQuest") {
            foreach ($arr as $key => $value) {
                $resArr[] = $key . " = ?";
            }
            $res = implode(",", $resArr);
        } else if ($command == "whereQuest") {
            $res = "";
            foreach ($arr as $key => $value) {
                $res .= $key . " = ? AND ";
            }
            $res = $res . "1 = 1";
        }

        return $res;
    }


    /* *
     * SELECT命令预处理绑定参数并执行的方法
     * @param  string  $sql     要执行的已经构造好的sql语句
     * @param  array   $where   用于绑定参数 键名键值一般对应WHERE子句中变量名和值
     * @param  string  $fetch   标记返回结果数组的形式 assoc为关联数组 num为索引数组 both为二者都有
     * @return array            数组形式的返回结果
     * */
    private function select_Exec($sql, $where, $fetch)
    {
        try {
            $this->prepare = $this->pdo->prepare($sql);
        } catch (PDOException $e) {
            print_r($e->errorInfo);
        }
        $this->bindParam("colon", $where);
        $this->prepare->execute();
        switch ($fetch) {
            case "num":
                $res = $this->prepare->fetchAll(PDO::FETCH_NUM);
                break;
            case "assoc":
                $res = $this->prepare->fetchAll(PDO::FETCH_ASSOC);
                break;
            case "both":
                $res = $this->prepare->fetchAll(PDO::FETCH_BOTH);
                break;
            default:
                $res = $this->prepare->fetchAll(PDO::FETCH_BOTH);
        }
        return $res;
    }


    /*
     * SELECT命令直接执行的方法
     * @param  string  $sql     要执行的已经构造好的sql语句
     * @param  string  $fetch   标记返回结果数组的形式 assoc为关联数组 num为索引数组 both为二者都有
     * @return array            数组形式的返回结果
     * */
    private function selectExec($sql, $fetch)
    {
        $res = $this->pdo->query($sql);
        switch ($fetch) {
            case "num":
                $res = $res->fetchAll(PDO::FETCH_NUM);
                break;
            case "assoc":
                $res = $res->fetchAll(PDO::FETCH_ASSOC);
                break;
            case "both":
                $res = $res->fetchAll(PDO::FETCH_BOTH);
                break;
            default:
                $res = $res->fetchAll(PDO::FETCH_BOTH);
        }
        return $res;
    }


    /* *
     * INSERT命令的预处理绑定参数并执行
     * @param   string $sql   要执行的已经构造好的sql语句
     * @param   array  $data  用于绑定参数的数组 键名键值一般对应变量名和值
     * @return  int           返回受影响记录的数目
     * */
    private function insert_Exec($sql, $data)
    {
        try {
            $this->prepare = $this->pdo->prepare($sql);
        } catch (PDOException $e) {
            print_r($e->errorInfo);
        }
        $this->bindParam("colon", $data);
        $this->prepare->execute();
        $res = $this->prepare->rowCount();
        return $res;
    }


    /* *
     * UPDATE命令的预处理绑定参数并执行
     * @param   string $sql   要执行的已经构造好的sql语句
     * @param   array  $data  用于绑定参数的数组 键名键值一般对应变量名和值
     * @param   array  $where 用于绑定参数 键名键值一般对应WHERE子句中变量名和值
     * @return  int           返回受影响记录的数目
     * */
    private function update_Exec($sql, $data, $where)
    {
        try {
            $this->prepare = $this->pdo->prepare($sql);
        } catch (PDOException $e) {
            print_r($e->getMessage());
        }
        $this->bindParam("quest", array($data, $where));
        $this->prepare->execute();
        $res = $this->prepare->rowCount();
        return $res;
    }


    /* *
     * INSERT/UPDATE/DELETE 等命令直接执行的方法
     * @param   string $sql   构造好的要执行的sql语句
     * @return  int           返回受影响记录的数目
     * */
    private function normalExec($sql)
    {
        try {
            $res = $this->pdo->exec($sql);
        } catch (PDOException $e) {
            print_r($e->getMessage());
        }
        return $res;
    }


    /* *
     * sql语句经过预处理语句后绑定参数的方法
     * @flag    string  $flag   用于标记绑定参数的类型  quest为变量为问号的类型 colon为变量为冒号加变量名的格式
     * @param   array   $param  用于绑定的数组 键名键值一般分别对应为变量名和值
     * @return  null
     * */
    private function bindParam($flag, $param)
    {
        if (empty($param))
            return;
        if ($flag == "quest") {
            $dataCount = count($param[0]);
            $whereCount = count($param[1]);
            $dataArr = array_values($param[0]);
            $whereArr = array_values($param[1]);
            $j = 1;
            for ($i = 0; $i < $dataCount; $i++, $j++) {
                $this->prepare->bindValue($j, $dataArr[$i]);
            }
            for ($i = 0; $i < $whereCount; $i++, $j++) {
                $this->prepare->bindValue($j, $whereArr[$i]);
            }
        } else if ($flag == "colon") {
            foreach ($param as $key => $value) {
                $this->prepare->bindValue(":" . $key, $value);
            }
        }

    }


}//end class