封裝:PDO與MySQL之間的無縫切換
阿新 • • 發佈:2017-09-24
params argument isset 釋放 結果 pdo ror exe tco
以下的例子是將MySQL和PDO封裝好,再無縫切換:
文件目錄:
config.php文件:
<?php return array( // 數據庫配置 ‘DB‘ => array( ‘default_extension‘=>‘mysql‘, //這裏可以是pdo或mysql ), // 分頁配置 // 上傳配置 // 圖像處理配置 );
I_DB.interface.php文件:
<?php /** * 數據庫接口 */ interface I_DB {public static function getInstance($config);// 獲取單例對象 public function my_query($sql); //執行增刪改 public function fetchAll($sql); //查詢所有 public function fetchRow($sql); //查詢一行 public function fetchColumn($sql); //查詢一個單行單列的一個值 }
MySQLDB.class.php文件:
<?php header(‘content-type:text/html;charset=utf-8‘);/** * MySQL數據庫工具類 */ //加載接口 include ‘./I_DB.interface.php‘; class MySQLDB implements I_DB{ private $host; //主機地址 private $port; //端口號 private $user; //用戶名 private $pass; //密碼 private $dbname; //數據庫名 private $charset;//字符集 private $link; //保存連接數據庫資源 privatestatic $instance = null; //單例模式中的$MySQLDB對象 /** *@param array $config 配置文件 */ private function __construct ($config) { // 初始化屬性的值 $this->init($config); // 連接數據庫 $this->my_connect(); // 設置字符集 $this->my_charset(); // 選擇數據庫 $this->my_dbname(); } /** * 只能new一次,單例模式 *@param array $config 傳遞給構造方法的數組參數 */ public static function getInstance($config) { if (self::$instance == null) { self::$instance = new self($config); } return self::$instance; } /*** *私有化克隆魔術方法 */ private function _clone() {} /** *初始化 *@param array $config 傳遞給初始化方法的數組參數 */ private function init($config) { $this->host = isset($config[‘host‘])?$config[‘host‘]:‘localhost‘; $this->port = isset($config[‘port‘])?$config[‘port‘]:‘3306‘; $this->user = isset($config[‘user‘])?$config[‘user‘]:‘root‘; $this->pass = isset($config[‘pass‘])?$config[‘pass‘]:‘‘; $this->dbname = isset($config[‘dbname‘])?$config[‘dbname‘]:‘‘; $this->charset = isset($config[‘charset‘])?$config[‘charset‘]:‘utf8‘; } /** *錯誤測試方法 *@param string $sql sql語句 *直接用途:用來增刪改 */ public function my_query($sql) { if ($result = mysql_query($sql)) { return $result; }else { echo "執行sql語句失敗;<br/>"; echo "錯誤代碼:",mysql_errno(),"<br/>"; echo "錯誤信息:",mysql_error(),‘<br/>‘; return false; } } /** *連接數據庫 */ private function my_connect() { if ($link = mysql_connect("$this->host:$this->port",$this->user,$this->pass)) { $this->link = $link; }else { echo "連接數據庫失敗:<br/>"; echo "錯誤代碼:",mysql_errno(),"<br/>"; echo "錯誤信息:",mysql_error(),‘<br/>‘; return false; } } /** *設置字符集 */ private function my_charset() { $sql = "set names $this->charset"; $this->my_query($sql); } /** *選擇數據庫 */ private function my_dbname() { $sql = "use $this->dbname"; return $this->my_query($sql); } /** *返回多行多列的結果集,二維數組 *@param string sql語句 *@return mixed(array|false) *執行成功返回數組,失敗返回false */ public function fetchAll($sql) { if($result = $this->my_query($sql)) { //返回資源結果集,遍歷 $rows[] = ‘‘; while ($row = mysql_fetch_assoc($result)) { $rows[] = $row; } //結果集使用完畢,主動釋放 mysql_free_result($result); //返回二維數組 return $rows; } else { return false; } } /** * 返回一行多列的結果集,一維數組 *@param string 一條sql語句 *@return mixed(array|false) 執行成功返回數組,失敗返回false */ public function fetchRow($sql) { if($result = $this->my_query($sql)) { //返回資源結果集,遍歷 $row = mysql_fetch_assoc($result); //結果集使用完畢,主動釋放 mysql_free_result($result); //返回一維數組 return $row; } else { return false; } } /** *返回一行一列的結果集,單一值 *@param string 一條sql語句 *@return mixed(array|false) 執行成功返回數組,失敗返回false */ public function fetchColumn($sql) { if($result = $this->my_query($sql)) { //返回資源結果集,提取 $row = mysql_fetch_row($result); //結果集使用完畢,主動釋放 mysql_free_result($result); //返回單一值 return isset($row[0])?$row[0]:false; } else { return false; } } /** *析構方法 */ public function __destruct() { @mysql_close($this->link); } /** *__sleep 序列化對象的時候觸發執行 */ public function __sleep() { return array(‘host‘,‘port‘,‘user‘,‘pass‘,‘charset‘,‘dbname‘) ; } /** *__wakeup 反序列化的時候觸發執行 *初始化操作 */ public function __wakeup() { //初始化操作 // 連接數據庫 $this->my_connect(); // 設置字符集 $this->my_charset(); // 選擇數據庫 $this->my_dbname(); } /** *__set 為一個不可訪問的屬性賦值的時候自動觸發 *@param string $name 屬性名 *@param mixed $value 屬性值 */ public function __set($name,$value) { $allow_set = array(‘host‘,‘port‘,‘user‘,‘pass‘,‘dbname‘,‘charset‘); if(in_array($name,$allow_set)) { //當前屬性可以被賦值 $this->$name = $value; } } /** *__get *獲得一個不可訪問的屬性的值的時候自動觸發 *@param string $name 屬性名 */ public function __get($name) { $allow_get = array(‘host‘,‘port‘,‘user‘,‘pass‘,‘dbname‘,‘charset‘); if (in_array($name,$allow_get)) { return $this->$name; } } /** *__call 訪問一個不可訪問的對象方法的時候觸發 *@param string $name *@param array $argument 參數列表 */ public function __call($name, $argument) { echo "對不起,您訪問的".$name."()方法不存在!<br/>"; } /** *__callstatic 訪問一個不可訪問的類方法(靜態方法)的時候觸發 *@param string $name *@param array $argument 參數列表 */ public static function __callStatic($name, $argument) { echo "對不起,您訪問的".$name."()靜態方法不存在!<br/>"; } }
PDODB.class.php文件:
<?php header(‘content-type:text/html;charset=utf-8‘); /** * 封裝PDODB類 */ // 加載接口 include ‘./I_DB.interface.php‘; class PDODB implements I_DB { /** * 定義相關屬性 */ private $host; //主機地址 private $port; //端口號 private $user; //用戶名 private $pass; //密碼 private $dbname; //數據庫名 private $charset;//字符集 private $dsn; //數據源名稱 private $pdo; //用於存放PDO的一個對象 // 靜態私有屬性用於保存單例對象 private static $instance; /** * [__construct 構造方法] * @param [array] $config [配置數組] */ private function __construct($config) { // 初始化屬性 $this->initParams($config); // 初始化dsn $this->initDSN(); // 實例化PDO對象 $this->initPDO(); // 初始化PDO對象的屬性 $this->initAttribute(); } /** * [getInstance 獲取PDO單例對象的公開方法] * @param [array] $config [description] * @return [PDOobject] self::$instance [pdo對象] */ public static function getInstance($config) { if (!self::$instance instanceof self) { self::$instance = new self($config); } return self::$instance; } /** * [initParams 初始化屬性] * @param [array] $config [配置數組] */ private function initParams($config) { $this->host = isset($config[‘host‘])?$config[‘host‘]:‘localhost‘; $this->port = isset($config[‘port‘])?$config[‘port‘]:‘3306‘; $this->user = isset($config[‘user‘])?$config[‘user‘]:‘root‘; $this->pass = isset($config[‘pass‘])?$config[‘pass‘]:‘‘; $this->dbname = isset($config[‘dbname‘])?$config[‘dbname‘]:‘‘; $this->charset = isset($config[‘charset‘])?$config[‘charset‘]:‘utf8‘; } /** * [initDSN 初始化dsn] */ private function initDSN() { $this->dsn = "mysql:host=$this->host;port=$this->port;dbname=$this->dbname;charset=$this->charset"; } /** * [initPDO 實例化PDO對象] * @return [boolean] [false|none] */ private function initPDO() { // 在實例化PDO對象的時候自動的走異常模式(也是唯一走異常模式的地方) try{ $this->pdo = new PDO($this->dsn,$this->user,$this->pass); }catch(PDOException $e) { $this->my_error($e); } } /** * [initAttribute 初始化PDO對象屬性] * @return [boolean] [false|none] */ private function initAttribute() { // 修改錯誤模式為異常模式 $this->pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); } /** * [my_error 輸出異常信息] * @param [PDOException] $e [異常對象] * @return [boolean] [false|none] */ private function my_error($e) { echo "執行sql語句失敗!<br/>"; echo "錯誤的代碼是:",$e->getCode(),"<br/>"; echo "錯誤的信息是:",$e->getMessage(),"<br/>"; echo "錯誤的腳本是:",$e->getFile(),"<br/>"; echo "錯誤的行號是:",$e->getLine(),‘<br/>‘; return false; } /** * [my_query 執行一條sql語句,實現增刪改] * @param [string] $sql [sql語句] * @return [array] $result [資源結果集] */ public function my_query($sql) { // 其實就是調用pdo對象中的exec方法 try{ $result = $this->pdo->exec($sql); }catch(PDOException $e) { $this->my_error($e); } return $result; } /** * [fetchAll 查詢所有] * @param [string] $sql [sql語句] * @return [arry] $result [資源結果集] */ public function fetchAll($sql) { // 其實就是調用PDOStatment對象裏面的fetchAll方法 try{ $stmt = $this->pdo->query($sql); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); // 關閉遊標,釋放結果集 $stmt->closeCursor(); }catch(PDOException $e) { $this->my_error($e); } return $result; } /** * [fetchRow 查詢一條] * @param [string] $sql [sql語句] * @return [arry] $result [資源結果集] */ public function fetchRow($sql) { // 其實就是調用PDOStatment對象裏面的fetch方法 try{ $stmt = $this->pdo->query($sql); $result = $stmt->fetch(PDO::FETCH_ASSOC); // 關閉遊標,釋放結果集 $stmt->closeCursor(); }catch(PDOException $e) { $this->my_error($e); } return $result; } /** * [fetchColumn 查詢單行單列] * @param [string] $sql [sql語句] * @return [arry] $result [資源結果集] */ public function fetchColumn($sql) { // 其實就是調用PDOStatment對象裏面的fetchColumn方法 try{ $stmt = $this->pdo->query($sql); $result = $stmt->fetchColumn(); // 關閉遊標,釋放結果集 $stmt->closeCursor(); }catch(PDOException $e) { $this->my_error($e); } return $result; } /** * [__clone 私有化克隆方法,保護單例模式] */ private function __clone() {} /** * [__set 為一個不可訪問的屬性賦值的時候自動觸發] * @param [string] $name [屬性名] * @param [mixed] $value [屬性值] */ public function __set($name,$value) { $allow_set = array(‘host‘,‘port‘,‘user‘,‘pass‘,‘dbname‘,‘charset‘); if(in_array($name,$allow_set)) { //當前屬性可以被賦值 $this->$name = $value; } } /** * [__get *獲得一個不可訪問的屬性的值的時候自動觸發] * @param [string] $name [屬性名] * @return [string] $name的value [該屬性名的值] */ public function __get($name) { $allow_get = array(‘host‘,‘port‘,‘user‘,‘pass‘,‘dbname‘,‘charset‘); if (in_array($name,$allow_get)) { return $this->$name; } } /** * [__call 訪問一個不可訪問的對象方法的時候觸發] * @param [string] $name [屬性名] * @param [array] $argument [參數列表] */ public function __call($name, $argument) { echo "對不起,您訪問的".$name."()方法不存在!<br/>"; } /** * [__callstatic 訪問一個不可訪問的類方法(靜態方法)的時候觸發] * @param [string] $name [屬性名] * @param [array] $argument [參數列表] */ public static function __callStatic($name, $argument) { echo "對不起,您訪問的".$name."()靜態方法不存在!<br/>"; } }
最後的測試類:
<?php header(‘content-type:text/html;charset=utf-8‘); // 先讀取配置文件 $conf = include ‘./config.php‘; $config = [ ‘pass‘=>‘123456‘, ‘dbname‘=>‘bbs‘ ]; // 實例化數據庫操作對象 switch ($conf[‘DB‘][‘default_extension‘]) { case ‘mysql‘: include ‘./MySQLDB.class.php‘; $db = MySQLDB::getInstance($config); break; case ‘pdo‘: include ‘./PDODB.class.php‘; $db = PDODB::getInstance($config); break; default: break; } $sql = "select * from user limit 4"; echo "<pre>"; var_dump($db->fetchAll($sql)); echo "</pre>"; echo "<hr>";
測試結果:
還可以在配置文件config.php中切換到pdo中操作數據庫!
封裝:PDO與MySQL之間的無縫切換