zoukankan      html  css  js  c++  java
  • 一個PDO操作類

    <?php
    
    /*
    *    Author: AthrunSoft
    *    class.pdomysql.php 0.01 2012-4-15
    */
    class pdomysql {
        public static $dbtype = 'mysql';
        public static $dbhost = '';
        public static $dbport = '';
        public static $dbname = '';
        public static $dbuser = '';
        public static $dbpass = '';
        public static $charset = '';
        public static $stmt = null;
        public static $DB = null;
        public static $connect = true; //是否長連接
       public static $debug = false;
        private static $parms = array();
    
        /**
         * 構造函數
         */
        public function __construct() {
            self::$dbtype = 'mysql';
            self::$dbhost = DBHOST;
            self::$dbport = DBPORT;
            self::$dbname = DBNAME;
            self::$dbuser = DBUSER;
            self::$dbpass = DBPASS;
            self::$connect = ISCONNECT;
            self::$charset = CHARSET;
            self::connect();
            self::$DB->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
            self::$DB->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
            self::execute('SET NAMES ' . self::$charset);
        }
        /**
         *析構函數
         */
        public function __destruct() {
            self::close();
        }
    
    
        /*********************基本方法開始*********************/
        /**
         * 作用:連結資料庫
         */
        public function connect() {
            try {
                self::$DB = new PDO(self::$dbtype . ':host=' . self::$dbhost . ';port=' . self::
                    $dbport . ';dbname=' . self::$dbname, self::$dbuser, self::$dbpass, array(PDO::
                    ATTR_PERSISTENT => self::$connect));
            }
            catch (PDOException $e) {
                die("Connect Error Infomation:" . $e->getMessage());
            }
        }
    
        /**
         *關閉資料連接
         */
        public function close() {
            self::$DB = null;
        }
    
        /**
         * 對字串進行轉義
         */
        public function quote($str) {
            return self::$DB->quote($str);
        }
    
        /**
         * 返回一個日期時間字符
         */
        public function now() {
            return date("Y-m-d H:i:s");
        }
        /**
         * 作用:獲取當前庫的所有表名
         * 返回:當前庫的所有表名
         * 類型:陣列
         */
        public function getTablesName() {
            self::$stmt = self::$DB->query('SHOW TABLES FROM ' . self::$dbname);
            $result = self::$stmt->fetchAll(PDO::FETCH_NUM);
            self::$stmt = null;
            return $result;
        }
    
        /**
         * 作用:獲取資料表裡的欄位
         * 返回:表字段結構
         * 類型:陣列
         */
        public function getFields($table) {
            self::$stmt = self::$DB->query("DESCRIBE $table");
            $result = self::$stmt->fetchAll(PDO::FETCH_ASSOC);
            self::$stmt = null;
            return $result;
        }
    
        /**
         * 作用:獲得最後INSERT的主鍵ID
         * 返回:最後INSERT的主鍵ID
         * 類型:數字
         */
        public function getLastId() {
            return self::$DB->lastInsertId();
        }
    
        /**
         *事務開始
         */
        public function autocommit() {
            self::$DB->beginTransaction();
        }
    
        /**
         *事務提交
         */
        public function commit() {
            self::$DB->commit();
        }
    
        /**
         *交易復原
         */
        public function rollback() {
            self::$DB->rollback();
        }
    
        /**
         * 作用:執行INSERT\UPDATE\DELETE
         * 返回:執行語句影響行數
         * 類型:數字
         */
        public function execute($sql) {
            self::getPDOError($sql);
            return self::$DB->exec($sql);
        }
    
        /**
         * 獲取要操作的資料
         * 返回:合併後的SQL語句
         * 類型:字串
         */
        private function getCode($table, $args) {
            $code = '';
            if (is_array($args)) {
                foreach ($args as $k => $v) {
                    if ($v == '') {
                        continue;
                    }
                    $code .= "`$k`='$v',";
                }
            }
            $code = substr($code, 0, -1);
            return $code;
        }
    
        /**
         * 執行具體SQL操作
         * 返回:運行結果
         * 類型:陣列或數位
         */
        private function _fetch($sql, $type) {
            $result = array();
            self::$stmt = self::$DB->query($sql);
            self::getPDOError($sql);
            self::$stmt->setFetchMode(PDO::FETCH_ASSOC);
            switch ($type) {
                case '0':
                    $result = self::$stmt->fetch();
                    break;
                case '1':
                    $result = self::$stmt->fetchAll();
                    break;
                case '2':
                    if ($sql) {
                        $result = self::$stmt->fetchColumn();
                    } elseif (self::$stmt) {
                        $result = self::$stmt->rowCount();
                    } else {
                        $result = 0;
                    }
                    break;
            }
            self::$stmt = null;
            return $result;
        }
    
        /**
         * 分頁計算
         */
        private function count($pagesize, &$page, &$pagecount, &$recordcount) {
            //獲取記錄行數,計算頁數,以及重新檢查當前頁碼
            $pagecount = ceil($recordcount / $pagesize);
            if ($pagecount > 0) {
                if ($page > $pagecount) {
                    $page = $pagecount;
                } elseif ($page < 1) {
                    $page = 1;
                }
            } else {
                $page = 1;
            }
        }
        /*********************基本方法結束*********************/
    
    
        /*********************Sql操作方法開始*********************/
        /**
         * 作用:插入資料
         * 返回:表內記錄
         * 類型:陣列
         * 參數:$db->insert('$table',array('title'=>'Zxsv'))
         */
        public function add($table, $args) {
            $sql = "INSERT INTO `$table` SET ";
            $code = self::getCode($table, $args);
            $sql .= $code;
            return self::execute($sql);
        }
    
        /**
         * 修改資料
         * 返回:記錄數
         * 類型:數字
         * 參數:$db->update($table,array('title'=>'Zxsv'),array('id'=>'1'),$where ='id=3');
         */
        public function update($table, $args, $where) {
            $code = self::getCode($table, $args);
            $sql = "UPDATE `$table` SET ";
            $sql .= $code;
            $sql .= " Where $where";
            return self::execute($sql);
        }
    
        /**
         * 作用:刪除資料
         * 返回:表內記錄
         * 類型:陣列
         * 參數:$db->delete($table,$condition = null,$where ='id=3')
         */
        public function delete($table, $where) {
            $sql = "DELETE FROM `$table` Where $where";
            return self::execute($sql);
        }
    
        /**
         * 作用:獲取單行資料
         * 返回:表內第一條記錄
         * 類型:陣列
         * 參數:$db->fetOne($table,$condition = null,$field = '*',$where ='')
         */
        public function fetOne($table, $field = '*', $where = false) {
            $sql = "SELECT {$field} FROM `{$table}`";
            $sql .= ($where) ? " WHERE $where" : '';
            return self::_fetch($sql, $type = '0');
        }
    
        /**
         * 作用:獲取單行資料
         * 返回:表內第一條記錄
         * 類型:陣列
         * 參數:select * from table where id='1'
         */
        public function getOne($sql) {
            return self::_fetch($sql, $type = '0');
        }
        /**
         * 作用:獲取首行首列資料
         * 返回:首行首列欄位值
         * 類型:值
         * 參數:select `a` from table where id='1'
         */
        public function scalar($sql, $fieldname) {
            $row = self::_fetch($sql, $type = '0');
            return $row[$fieldname];
        }
        /**
         * 獲取記錄總數
         * 返回:記錄數
         * 類型:數字
         * 參數:$db->fetRow('$table',$condition = '',$where ='');
         */
        public function fetRowCount($table, $field = '*', $where = false) {
            $sql = "SELECT COUNT({$field}) AS num FROM `$table`";
            $sql .= ($where) ? " WHERE $where" : '';
            return self::_fetch($sql, $type = '2');
        }
    
        /**
         * 獲取記錄總數
         * 返回:記錄數
         * 類型:數字
         * 參數:select count(*) from table
         */
        public function getRowCount($sql) {
            return self::_fetch($sql, $type = '2');
        }
        /**
         * 作用:獲取所有資料
         * 返回:表內記錄
         * 類型:二維陣列
         * 參數:$db->fetAll('$table',$condition = '',$field = '*',$orderby = '',$limit = '',$where='')
         */
        public function fetAll($table, $field = '*', $orderby = false, $where = false) {
            $sql = "SELECT {$field} FROM `{$table}`";
            $sql .= ($where) ? " WHERE $where" : '';
            $sql .= ($orderby) ? " ORDER BY $orderby" : '';
            return self::_fetch($sql, $type = '1');
        }
        /**
         * 作用:獲取分頁資料
         * 返回:表內記錄
         * 類型:二維陣列
         */
        public function fetPageAll($table, $field = '*', $where = false, $orderby = false,
            $pagesize, &$page, &$pagecount, &$recordcount) {
            $sql = "SELECT {$field} FROM `{$table}`";
            $sql .= ($where) ? " WHERE $where" : '';
            return self::getPageAll($sql, $orderby, $pagesize, $page, $pagecount, $recordcount);
        }
        /**
         * 作用:獲取所有資料
         * 返回:表內記錄
         * 類型:二維陣列
         * 參數:select * from table
         */
        public function getAll($sql) {
            return self::_fetch($sql, $type = '1');
        }
    
        /**
         * 作用:獲取分頁資料
         * 返回:表內記錄
         * 類型:二維陣列
         */
        public function getPageAll($sql, $orderby = false, $pagesize, &$page, &$pagecount,
            &$recordcount) {
            $sqlcount = "select count(1) as `recordcount` from ($sql) as t;";
            $recordcount = self::scalar($sqlcount, 'recordcount');
            self::count($pagesize, $page, $pagecount, $recordcount);
            $start = ($page - 1) * $pagesize;
            $sql .= ($orderby) ? " ORDER BY $orderby" : '';
            $sql .= " limit $start,$pagesize";
            return self::_fetch($sql, $type = '1');
        }
        /*********************Sql操作方法結束*********************/
    
        /*********************Pram操作方法開始*********************/
        /**
         * 作用:獲取單行資料
         * 返回:表內第一條記錄
         * 類型:陣列
         */
        public function pramGetOne($sql, $input_parameters) {
            return self::_pramfetch($sql, $input_parameters, $type = '0');
        }
        /**
         * 作用:獲取所有資料
         * 返回:表內記錄
         * 類型:二維陣列
         */
        public function pramGetAll($sql, $input_parameters) {
            return self::_pramfetch($sql, $input_parameters, $type = '1');
        }
        /**
         * 作用:執行帶參數SQL操作
         * 返回:執行語句影響行數
         * 類型:數字
         */
        public function pramExecute($sql, $input_parameters) {
            return self::_pramfetch($sql, $input_parameters, $type = '2');
        }
        /**
         * 作用:獲取首行首列資料
         * 返回:首行首列欄位值
         * 類型:值
         */
        public function pramScalar($sql, $input_parameters, $fieldname) {
            $row = self::_pramfetch($sql, $input_parameters, $type = '0');
            return $row[$fieldname];
        }
        /**
         * 執行帶參數SQL操作
         * 返回:運行結果
         * 類型:陣列或數位
         */
        private function _pramfetch($sql, $input_parameters, $type) {
            $result = array();
            self::$stmt = self::$DB->prepare($sql);
            self::getPDOError($sql);
            self::$stmt->execute($input_parameters);
            self::getSTMTError($sql);
            self::$stmt->setFetchMode(PDO::FETCH_ASSOC);
            switch ($type) {
                case '0':
                    $result = self::$stmt->fetch();
                    break;
                case '1':
                    $result = self::$stmt->fetchAll();
                    break;
                case '2':
                    if (self::$stmt) {
                        $result = self::$stmt->rowCount();
                    } else {
                        $result = 0;
                    }
                    break;
            }
            self::$stmt = null;
            return $result;
        }
        /*********************Pram操作方法結束*********************/
    
    
        /*********************Proc操作方法開始*********************/
        /**
         * 添加參數
         */
        public function pramadd($parameter, $variable, $data_type, $length) {
            array_push(self::$parms, array($parameter, $variable, $data_type, $length));
        }
        /**
         * 清除所有參數
         */
        public function pramclear() {
            self::$parms = array();
        }
        /**
         * 作用:獲取單行資料
         * 返回:表內第一條記錄
         * 類型:陣列
         */
        public function procGetOne($sql) {
            return self::_procfetch($sql, $type = '0');
        }
        /**
         * 作用:獲取所有資料
         * 返回:表內記錄
         * 類型:二維陣列
         */
        public function procGetAll($sql) {
            return self::_procfetch($sql, $type = '1');
        }
        /**
         * 作用:執行一個存儲過程
         * 返回:執行語句影響行數
         * 類型:數字
         */
        public function procExecute($sql) {
            return self::_procfetch($sql, $type = '2');
        }
        /**
         * 作用:獲取out型的return
         */
        public function getReturn() {
            return self::scalar("select @ireturn AS iReturn", "iReturn");
        }
        /**
         * 執行帶參數SQL操作
         * 返回:運行結果
         * 類型:陣列或數位
         */
        private function _procfetch($sql, $type) {
            $result = array();
            self::$stmt = self::$DB->prepare($sql);
            self::getPDOError($sql);
            foreach (self::$parms as $pram) {
                self::$stmt->bindParam($pram[0], $pram[1], $pram[2], $pram[3]);
            }
            self::$stmt->execute();
            self::getSTMTError($sql);
            self::$stmt->setFetchMode(PDO::FETCH_ASSOC);
            switch ($type) {
                case '0':
                    $result = self::$stmt->fetch();
                    break;
                case '1':
    //                do{
    //                    $result[] = self::$stmt->fetchAll();
    //                } while (self::$stmt->nextRowset());
                    $result = self::$stmt->fetchAll();
                    self::$stmt->closeCursor();
                    break;
                case '2':
                    if (self::$stmt) {
                        $result = self::$stmt->rowCount();
                    } else {
                        $result = 0;
                    }
                    break;
            }
            self::$stmt = null;
            return $result;
        }
        
        /**
         * 權為測試使用,目前沒有辦法獲取到OUT參數.
         * 另外在一存講過程中若有rowset,同時還有OUT參數時,
         * 即使$db->scalar("select @Rcount AS Rcount", "Rcount")這种方式仍然獲到不到,
         * 執行時會出現下面的錯誤:
         * Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute.
         */
        public function procExecOut() {
            //$colour = 'red';
            self::$stmt = self::$DB->prepare('CALL puree_fruit(?)');
            self::$stmt->bindParam(1, $colour,PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 4000);
            self::$stmt->execute();
            print("After pureeing fruit, the colour is: $colour");
        }
        /*********************Proc操作方法結束*********************/
    
    
        /*********************錯誤處理開始*********************/
    
        /**
         * 設置是否為調試模式
         */
        public function setDebugMode($mode = true) {
            return ($mode == true) ? self::$debug = true : self::$debug = false;
        }
    
        /**
         * 捕獲PDO錯誤資訊
         * 返回:出錯資訊
         * 類型:字串
         */
        private function getPDOError($sql) {
            self::$debug ? self::errorfile($sql) : '';
            if (self::$DB->errorCode() != '00000') {
                $info = (self::$stmt) ? self::$stmt->errorInfo() : self::$DB->errorInfo();
                echo (self::sqlError('mySQL Query Error', $info[2], $sql));
                exit();
            }
        }
        private function getSTMTError($sql) {
            self::$debug ? self::errorfile($sql) : '';
            if (self::$stmt->errorCode() != '00000') {
                $info = (self::$stmt) ? self::$stmt->errorInfo() : self::$DB->errorInfo();
                echo (self::sqlError('mySQL Query Error', $info[2], $sql));
                exit();
            }
        }
    
        /**
         * 寫入錯誤日志
         */
        private function errorfile($sql) {
            echo $sql . '<br />';
            $errorfile = _ROOT . './dberrorlog.php';
            $sql = str_replace(array("\n", "\r", "\t", "  ", "  ", "  "), array(" ", " ",
                " ", " ", " ", " "), $sql);
            if (!file_exists($errorfile)) {
                $fp = file_put_contents($errorfile, "<?PHP exit('Access Denied'); ?>\n" . $sql);
            } else {
                $fp = file_put_contents($errorfile, "\n" . $sql, FILE_APPEND);
            }
    
        }
    
        /**
         * 作用:運行錯誤資訊
         * 返回:運行錯誤資訊和SQL語句
         * 類型:字元
         */
        private function sqlError($message = '', $info = '', $sql = '') {
            $html = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml">';
            $html .= '<head><title>mySQL Message</title><style type="text/css">body {margin:0px;color:#555555;font-size:12px;background-color:#efefef;font-family:Verdana} ol {margin:0px;padding:0px;} .w {800px;margin:100px auto;padding:0px;border:1px solid #cccccc;background-color:#ffffff;} .h {padding:8px;background-color:#ffffcc;} li {height:auto;padding:5px;line-height:22px;border-top:1px solid #efefef;list-style:none;overflow:hidden;}</style></head>';
            $html .= '<body><div class="w"><ol>';
            if ($message) {
                $html .= '<div class="h">' . $message . '</div>';
            }
            $html .= '<li>Date: ' . date('Y-n-j H:i:s', time()) . '</li>';
            if ($info) {
                $html .= '<li>SQLID: ' . $info . '</li>';
            }
            if ($sql) {
                $html .= '<li>Error: ' . $sql . '</li>';
            }
            $html .= '</ol></div></body></html>';
            return $html;
        }
        /*********************錯誤處理結束*********************/
    }
    
    ?>


    此类还有两个问题没有处理(基本也可以使用):

    1,在调用有out/inout参数的mysql存储过程时,没有办法像下面这样获取参数值,以下方法是官方的demo,可在我电脑上却从来没有获取到相应的值.

    /* Call a stored procedure with an INOUT parameter */
    $colour 'red'
    ;
    $sth $dbh->prepare('CALL puree_fruit(?)'
    );
    $sth->bindParam(1$colourPDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT12
    );
    $sth->execute
    ();
    print(
    "After pureeing fruit, the colour is: $colour"
    );

    2,因为上面没有办法用PDO::PARAM_INPUT_OUTPUT的方式来获到out值.因此我改以下面的方式处理.结果又遇到另一个错误.好像是说没办法返回多个rowset的问题.

    $db->pramclear();
    $db->pramadd(1, 3, PDO::PARAM_INT,4,false);
    $db->procGetAll("CALL UP_Banner_GetList(?,@Rcount);");
    $db->scalar("select @Rcount AS Rcount", "Rcount");

    错误信息:

    Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute.

    以上两个问题点在网上也找了很多资料,有的说是php的bug,也有的说在linux机器上不会有这样的问题.弄了这几天总的感觉是对pdo挺失望的.原以为自己可以封装好一个操作类,方便以后使用.希望哪位高手如果有也有此经历,请留言告之在下如何解决.谢谢!

  • 相关阅读:
    百度地图V1.5 LocalSearch增加浮动窗体的操作内容
    百度地图LV1.5实践项目开发工具类bmap.util.jsV1.1
    Jquery时间快捷控件(Jtime)配置v1.1
    百度地图LV1.5实践项目开发工具类bmap.util.jsV1.0
    Jquery时间快捷控件(Jtime)配置v1.0
    百度地图JavaScript API V1.5初级开发工具类
    Cocos2d-x可以实现的动画效果
    禁掉Apache web server签名 How to turn off server signature on Apache web server
    codevs 3372 选学霸(hash+并查集+多重背包)
    从头认识Spring-3.4 简单的AOP日志实现-扩展添加检查订单功能,以便记录并检測输入的參数
  • 原文地址:https://www.cnblogs.com/Athrun/p/pdo_class.html
Copyright © 2011-2022 走看看