PHP PDO操作MYSQL封裝類

cgdf 9年前發布 | 10K 次閱讀 PHP

<?php
/**

  • auther soulence
  • 調用數據類文件
  • modify 2015/06/12 */ class DBConnect { private $dbname = null; private $pdo = null; private $persistent = false; private $statement = null; private $lastInsID = null; private static $_instance = [];

    private function __construct($dbname,$attr) {

     $this->dbname = $dbname;
     $this->persistent = $attr;
    

    }

    public static function db($flag='r',$persistent=false) {

     if(!isset($flag)){
         $flag = 'r';
     }
    
     if (!class_exists('PDO'))
     {
         throw new Exception('not found PDO');
         return false; 
     }
     $mysql_server = Yaf_Registry::get('mysql');
     if(!isset($mysql_server[$flag])){
         return false;
     }
    
     $options_arr = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES '.$mysql_server[$flag]['charset'],PDO::ATTR_DEFAULT_FETCH_MODE=>PDO::FETCH_ASSOC);
     if($persistent === true){
         $options_arr[PDO::ATTR_PERSISTENT] = true;
     }
    
     try { 
         $pdo = new PDO($mysql_server[$flag]['connectionString'],$mysql_server[$flag]['username'],$mysql_server[$flag]['password'],$options_arr);
     } catch (PDOException $e) {  
         throw new Exception($e->getMessage()); 
         //exit('連接失敗:'.$e->getMessage()); 
         return false; 
     }
    
     if(!$pdo) { 
         throw new Exception('PDO CONNECT ERROR'); 
         return false; 
     } 
    
     return $pdo;
    

    }

    /**

    • 得到操作數據庫對象
    • @param string $dbname 對應的數據庫是誰
    • @param bool $attr 是否長連接
    • return false說明給定的數據庫不存在 */ public static function getInstance($dbname = 'r',$attr = false) { $mysql_server = Yaf_Registry::get('mysql'); if(!isset($mysql_server[$dbname])){

       return false;
      

      } $key = md5(md5($dbname.$attr,true)); if (!isset(self::$_instance[$key]) || !is_object(self::$_instance[$key]))

       self::$_instance[$key] = new self($dbname,$attr);
      

      return self::$_instance[$key]; }

      private function getConnect(){ $this->pdo = self::db($this->dbname,$this->persistent); }

      /**

    • 查詢操作
    • @param string $sql 執行查詢的sql語句
    • @param array $data 查詢的條件 格式為':id'=>$id,':name'=>$name或者為[1=>$id,2=>$name]
    • @param bool $one 是否返回一條內容 默認為否 */ public function query($sql, $data = [], $one = false) { if (!is_array($data) || empty($sql) || !is_string($sql))

       return false;
      
      

      $this->free();

      return $this->queryCommon($data,$sql,$one); }

      /**

    • 內部查詢的共用方法 */ private function queryCommon($data,$sql,$one) { $this->pdoExec($data,$sql);

      if ($one){

       return $this->statement->fetch(PDO::FETCH_ASSOC);
      

      }else{

       return $this->statement->fetchAll(PDO::FETCH_ASSOC);
      

      } }

      /**

    • 多條SQL語句的查詢操作
    • @param array $arr_sql 執行查詢的sql語句數組 格式為[$sql1,$sql2]
    • @param array $arr_data 查詢與$arr_sql對應的條件 格式為[':id'=>$id,':name'=>$name],[':id'=>$id,':name'=>$name]或者為[[1=>$id,2=>$name],[1=>$id,2=>$name]]
    • @param bool $one 是否返回一條內容 默認為否 這里如果設置為true那么每一條sql都只返回一條數據 */ public function queryes($arr_sql, $arr_data = [], $one = false) { if(!is_array($arr_sql) || empty($arr_sql) || !is_array($arr_data))

       return false;
      
      

      $this->free();

      $res = [];$i = 0; foreach ($arr_sql as $val) {

       if(!isset($arr_data[$i]))
           $arr_data[$i] = [];
       elseif(!is_array($arr_data[$i]))
           throw new Exception('Error where queryes sql:'.$val.' where:'.$arr_data[$i]);
      
       $res[] = $this->queryCommon($arr_data[$i],$val,$one);
       $i++;
      

      } return $res; }

      /**

    • 分頁封裝 *
    • @param string $sql
    • @param int $page 表示從第幾頁開始取
    • @param int $pageSize 表示每頁多少條
    • @param array $data 查詢的條件 */ public function limitQuery($sql, $page=0, $pageSize=20, $data = []) { $page = intval($page); if ($page < 0) {

       return [];
      

      } $pageSize = intval($pageSize); if ($pageSize > 0) { // pageSize 為0時表示取所有數據

       $sql .= ' LIMIT ' . $pageSize;
       if ($page > 0) {
           $start_limit = ($page - 1) * $pageSize;
           $sql .= ' OFFSET ' . $start_limit;
       }
      

      } return $this->query($sql, $data); }

      /**

    • 這個是用來進行添加 刪除 修改操作 使用事務操作
    • @param string $sql 執行查詢的sql語句
    • @param array $data 查詢的條件 格式為':id'=>$id,':name'=>$name或者為[1=>$id,2=>$name]
    • @param bool $Transaction 是否事務操作 默認為否 */ public function executeDDL($sql, $data = [],$Transaction = false){ if (!is_array($data) || !is_string($sql))

       return false;
      
      

      $this->free();

      if($Transaction)

       $this->pdo->beginTransaction();//開啟事務
      

      try{

       $this->execRes($data,$sql);
       if($Transaction)
           $this->pdo->commit();//事務提交
       return $this->lastInsID;
      

      } catch (Exception $e) {

       if($Transaction)
           $this->pdo->rollBack();//事務回滾
       throw new Exception('Error DDLExecute <=====>'.$e->getMessage());
       return false;
      

      } }

      /**

    • 這個是用來進行添加 刪除 修改操作 使用事務操作
    • 它是執行多條的
    • @param array $arr_sql 需要執行操作的SQL語句數組
    • @param array $arr_data 與數組對應SQL語句的條件
    • @param bool $Transaction 是否事務操作 默認為否 */ public function executeDDLes($arr_sql, $arr_data = [],$Transaction = false){

      if(!is_array($arr_sql) || empty($arr_sql) || !is_array($arr_data))

       return false;
      
      

      $res = [];

      $this->free();

      if($Transaction)

       $this->pdo->beginTransaction();//開啟事務
      

      try{

       $i = 0;
       foreach($arr_sql as $val){
           if(!isset($arr_data[$i]))
               $arr_data[$i] = [];
           elseif(!is_array($arr_data[$i])){
               if($Transaction)
                   $this->pdo->rollBack();//事務回滾
               throw new Exception('Error where DDLExecutees sql:'.$val.' where:'.$arr_data[$i]);
           }
      
           $this->execRes($arr_data[$i],$val);
           $res[] = $this->lastInsID;
           $i++;
       }
      
       if($Transaction)
           $this->pdo->commit();//事務提交
      
       return $res;
      

      } catch (Exception $e) {

       if($Transaction)
           $this->pdo->rollBack();//事務回滾
       throw new Exception('Error DDLExecutees array_sql:'.json_encode($arr_sql).' <=====>'.$e->getMessage());
       return false;
      

      } return $res; }

      /**

    • 此方法是用來計算查詢返回的條數 注意 它只支持SELECT COUNT(*) FROM TABLE...或者SELECT COUNT(0) FROM TABLE...方式
    • @param string $sql 查詢的sql語句
    • @param array $data SQL語句的條件 */ public function countRows($sql,$data = []){ if (!is_array($data) || empty($sql) || !is_string($sql))

       return false;
      

      $this->free();

      $res = $this->pdoExec($data,$sql);

      if($res == false)

       return false;
      
      

      return $this->statement->fetchColumn(); }

      /**

    • 此方法是用來計算查詢返回的條數 它是執行多條SQL
    • @param string $sql 查詢的sql語句
    • @param array $data SQL語句的條件 */ public function countRowses($arr_sql,$arr_data = []){

      if(!is_array($arr_sql) || empty($arr_sql) || !is_array($arr_data))

       return false;
      
      

      $res = [];

      $this->free(); $i = 0; foreach ($arr_sql as $val) {

       if(!isset($arr_data[$i]))
           $arr_data[$i] = [];
       elseif(!is_array($arr_data[$i]))
           throw new Exception('Error where CountRowses sql:'.$val.' where:'.$arr_data[$i]);
      
       $res1 = $this->pdoExec($arr_data[$i],$val);
      
       if($res1 == false)
           $res[] = false;
       else
           $res[] = $this->statement->fetchColumn();
      

      }

      return $res; }

      /**

    • 這里再提供一個方法 由于項目中會有很多需要提供開啟事務 然后再進行操作 最后提交
    • @param bool $Transaction 是否事務操作 默認為否 */ public function getDB($Transaction=false) { $this->Transaction = $Transaction; $this->getConnect(); if($Transaction === true)

       $this->pdo->beginTransaction();//開啟事務
      

      return $this; }

      /**

    • 此方法可以執行多次 它是執行DDL語句的
    • 注意 它是需要配合getDB和sQCommit一起使用 不能單獨使用哦
    • 如果沒有開啟事務 sQCommit方法可以不調用
    • @param string $sql 查詢的sql語句
    • @param array $data SQL語句的條件 */ public function execSq($sql,$data = []) { if($this->checkParams($sql,$data) === false)

       return false;
      
      

      try{

       $this->execRes($data,$sql);
       return $this->lastInsID;
      

      } catch (Exception $e) {

       if(isset($this->Transaction) && $this->Transaction === true)
           $this->pdo->rollBack();//事務回滾
       throw new Exception('Error execSq<=====>'.$e->getMessage());
       return false;
      

      } finally {

       if (!empty($this->statement))
       {
           $this->statement->closeCursor();
           unset($this->statement);
       }
      

      } }

      /**

    • 執行查詢的方法 它需要傳一個連接數據庫對象
    • @param string $sql 執行查詢的sql語句
    • @param array $data 查詢的條件 格式為':id'=>$id,':name'=>$name或者為[1=>$id,2=>$name]
    • @param bool $one 是否返回一條內容 默認為否 */ public function querySq($sql,$data = [],$one = false) { if($this->checkParams($sql,$data) === false)

       return false;
      
      

      return $this->pdoExecSq($sql,$data,[1,$one]); }

      /**

    • 分頁封裝 *
    • @param string $sql
    • @param int $page 表示從第幾頁開始取
    • @param int $pageSize 表示每頁多少條
    • @param array $data 查詢的條件 */ public function limitQuerySq($sql, $page=0, $pageSize=20, $data = []) { $page = intval($page); if ($page < 0) {

       return [];
      

      } $pageSize = intval($pageSize); if ($pageSize > 0) { // pageSize 為0時表示取所有數據

       $sql .= ' LIMIT ' . $pageSize;
       if ($page > 0) {
           $start_limit = ($page - 1) * $pageSize;
           $sql .= ' OFFSET ' . $start_limit;
       }
      

      } return $this->querySq($sql, $data); }

      /**

    • 此方法是用來計算查詢返回的條數 注意 它只支持SELECT COUNT(*) FROM TABLE...或者SELECT COUNT(0) FROM TABLE...方式
    • @param string $sql 查詢的sql語句
    • @param array $data SQL語句的條件 */ public function countRowsSq($sql,$data = []){ if($this->checkParams($sql,$data) === false)

       return false;
      

      return $this->pdoExecSq($sql,$data,[2]); }

      /**

    • 這里再提供一個方法 這是最后提交操作 如果沒有開啟事務 此方法最后可以不調用的 */ public function sQCommit() { if(empty($this->pdo) || !is_object($this->pdo))

       return false;
      

      if(isset($this->Transaction) && $this->Transaction === true)

       $this->pdo->commit();//提交事務
      

      unset($this->pdo); }

      /**

    • 內部調用方法
      */ public function checkParams($sql,$data) { if (empty($this->pdo) || !is_object($this->pdo) || !is_array($data) || empty($sql) || !is_string($sql))

       return false;
      
      

      return true; }

      /**

    • 內部調用方法
      */ private function pdoExecSq($sql,$data,$select = []){ try{

       $res = $this->pdoExec($data,$sql);
       if(empty($select))
           return $res;
       else{
           if($select[0] === 1){
               if($select[1] === true)
                   return $this->statement->fetch(PDO::FETCH_ASSOC);
               else
                   return $this->statement->fetchAll(PDO::FETCH_ASSOC);
           }elseif($select[0] === 2)
               return $this->statement->fetchColumn();
           else
               return false;
       }
      

      } catch (Exception $e) {

       throw new Exception($e->getMessage());
       return false;
      

      } finally {

       if (!empty($this->statement))
       {
           $this->statement->closeCursor();
           unset($this->statement);
       }
      

      } }

      /**

    • 內部調用方法
      */ private function execRes($data,$sql){

      $res = $this->pdoExec($data,$sql);

      $in_id = $this->pdo->lastInsertId();

      if (preg_match("/^\s*(INSERT\s+INTO|REPLACE\s+INTO)\s+/i", $sql) && !empty($in_id))

       $this->lastInsID = $in_id;
      

      else

       $this->lastInsID = $res;
      

      }

      /**

    • 內部調用方法 用來直接執行SQL語句的方法 */ private function pdoExec($data,$sql){ $this->statement = $this->pdo->prepare($sql); if (false === $this->statement)

       return false;
      

      if (!empty($data)) {

       foreach ($data as $k => $v)
       {
           $this->statement->bindValue($k, $v);
       }
      

      } $res = $this->statement->execute(); if (!$res) {

       throw new Exception('sql:'.$sql.'<====>where:'.json_encode($data).'<====>error:'.json_encode($this->statement->errorInfo()));
      

      }else{

       return $res;
      

      } }

      /**

    • 內部調用方法 用來釋放的 */ private function free() { if (is_null($this->pdo))

       $this->getConnect();
      
      

      if (!empty($this->statement)) {

       $this->statement->closeCursor();
       $this->statement = null;
      

      } } } ?></pre>

 本文由用戶 cgdf 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!