全新的PDO數據庫操作類(僅適用Mysql)


  1年前,也差不多剛開博那會,分享過一個pdo的數據庫操作類(可參見:http://www.cnblogs.com/hooray/archive/2011/06/30/2094743.html),與其說是類,其實就只是幾個封裝好的函數,整體略顯稚嫩,但也是這么個東西,在公司里也用了1年之久。如今公司規模變大了,產品也日益完善,曾經的那個數據庫操作函數雖說使用上沒出什么大問題,但為了更顯專業,花了1天時間重寫了這個,現在,它確實是個類了。

/**
 * 作者:胡睿
 * 日期:2012/07/21
 * 電郵:hooray0905@foxmail.com
 */
 
class HRDB{
	protected $pdo;
	protected $res;
	protected $config;
	
	/*構造函數*/
	function __construct($config){
		$this->Config = $config;
		$this->connect();
	}
	
	/*數據庫連接*/
	public function connect(){
		$this->pdo = new PDO($this->Config['dsn'], $this->Config['name'], $this->Config['password']);
		$this->pdo->query('set names utf8;');
		//把結果序列化成stdClass
		//$this->pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
		//自己寫代碼捕獲Exception
		$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
	}
	
	/*數據庫關閉*/
	public function close(){
		$this->pdo = null;
	}
	
	public function query($sql){
		$res = $this->pdo->query($sql);
		if($res){
			$this->res = $res;
		}
	}
	public function exec($sql){
		$res = $this->pdo->exec($sql);
		if($res){
			$this->res = $res;
		}
	}
	public function fetchAll(){
		return $this->res->fetchAll();
	}
	public function fetch(){
		return $this->res->fetch();
	}
	public function fetchColumn(){
		return $this->res->fetchColumn();
	}
	public function lastInsertId(){
		return $this->res->lastInsertId();
	}
	
	/**
	 * 參數說明
	 * int				$debug		是否開啟調試,開啟則輸出sql語句
	 *								0	不開啟
	 *								1	開啟
	 *								2	開啟並終止程序
	 * int				$mode		返回類型
	 *								0	返回多條記錄
	 *								1	返回單條記錄
	 *								2	返回行數
	 * string/array		$table		數據庫表,兩種傳值模式
	 *								普通模式:
	 *								'tb_member, tb_money'
	 *								數組模式:
	 *								array('tb_member', 'tb_money')
	 * string/array		$fields		需要查詢的數據庫字段,允許為空,默認為查找全部,兩種傳值模式
	 *								普通模式:
	 *								'username, password'
	 *								數組模式:
	 *								array('username', 'password')
	 * string/array		$sqlwhere	查詢條件,允許為空,兩種傳值模式
	 *								普通模式:
	 *								'and type = 1 and username like "%os%"'
	 *								數組模式:
	 *								array('type = 1', 'username like "%os%"')
	 * string			$orderby	排序,默認為id倒序
	 */
	public function select($debug, $mode, $table, $fields="*", $sqlwhere="", $orderby="tbid desc"){
		//參數處理
		if(is_array($table)){
			$table = implode(', ', $table);
		}
		if(is_array($fields)){
			$fields = implode(', ', $fields);
		}
		if(is_array($sqlwhere)){
			$sqlwhere = ' and '.implode(' and ', $sqlwhere);
		}
		//數據庫操作
		if($debug === 0){
			if($mode === 2){
				$this->query("select count(tbid) from $table where 1=1 $sqlwhere");
				$return = $this->fetchColumn();
			}else if($mode === 1){
				$this->query("select $fields from $table where 1=1 $sqlwhere order by $orderby");
				$return = $this->fetch();
			}else{
				$this->query("select $fields from $table where 1=1 $sqlwhere order by $orderby");
				$return = $this->fetchAll();
			}
			return $return;
		}else{
			if($mode === 2){
				echo "select count(tbid) from $table where 1=1 $sqlwhere";
			}else if($mode === 1){
				echo "select $fields from $table where 1=1 $sqlwhere order by $orderby";
			}
			else{
				echo "select $fields from $table where 1=1 $sqlwhere order by $orderby";
			}
			if($debug === 2){
				exit;
			}
		}
	}
	
	/**
	 * 參數說明
	 * int				$debug		是否開啟調試,開啟則輸出sql語句
	 *								0	不開啟
	 *								1	開啟
	 *								2	開啟並終止程序
	 * int				$mode		返回類型
	 *								0	無返回信息
	 *								1	返回執行條目數
	 *								2	返回最后一次插入記錄的id
	 * string/array		$table		數據庫表,兩種傳值模式
	 *								普通模式:
	 *								'tb_member, tb_money'
	 *								數組模式:
	 *								array('tb_member', 'tb_money')
	 * string/array		$set		需要插入的字段及內容,兩種傳值模式
	 *								普通模式:
	 *								'username = "test", type = 1, dt = now()'
	 *								數組模式:
	 *								array('username = "test"', 'type = 1', 'dt = now()')
	 */
	public function insert($debug, $mode, $table, $set){
		//參數處理
		if(is_array($table)){
			$table = implode(', ', $table);
		}
		if(is_array($set)){
			$set = implode(', ', $set);
		}
		//數據庫操作
		if($debug === 0){
			if($mode === 2){
				$this->query("insert into $table set $set");
				$return = $this->lastInsertId();
			}else if($mode === 1){
				$this->exec("insert into $table set $set");
				$return = $this->res;
			}else{
				$this->query("insert into $table set $set");
				$return = NULL;
			}
			return $return;
		}else{
			echo "insert into $table set $set";
			if($debug === 2){
				exit;
			}
		}
	}
	
	/**
	 * 參數說明
	 * int				$debug		是否開啟調試,開啟則輸出sql語句
	 *								0	不開啟
	 *								1	開啟
	 *								2	開啟並終止程序
	 * int				$mode		返回類型
	 *								0	無返回信息
	 *								1	返回執行條目數
	 * string			$table		數據庫表,兩種傳值模式
	 *								普通模式:
	 *								'tb_member, tb_money'
	 *								數組模式:
	 *								array('tb_member', 'tb_money')
	 * string/array		$set		需要更新的字段及內容,兩種傳值模式
	 *								普通模式:
	 *								'username = "test", type = 1, dt = now()'
	 *								數組模式:
	 *								array('username = "test"', 'type = 1', 'dt = now()')
	 * string/array		$sqlwhere	修改條件,允許為空,兩種傳值模式
	 *								普通模式:
	 *								'and type = 1 and username like "%os%"'
	 *								數組模式:
	 *								array('type = 1', 'username like "%os%"')
	 */
	public function update($debug, $mode, $table, $set, $sqlwhere=""){
		//參數處理
		if(is_array($table)){
			$table = implode(', ', $table);
		}
		if(is_array($set)){
			$set = implode(', ', $set);
		}
		if(is_array($sqlwhere)){
			$sqlwhere = ' and '.implode(' and ', $sqlwhere);
		}
		//數據庫操作
		if($debug === 0){
			if($mode === 1){
				$this->exec("update $table set $set where 1=1 $sqlwhere");
				$return = $this->res;
			}else{
				$this->query("update $table set $set where 1=1 $sqlwhere");
				$return = NULL;
			}
			return $return;
		}else{
			echo "update $table set $set where 1=1 $sqlwhere";
			if($debug === 2){
				exit;
			}
		}
	}
	
	/**
	 * 參數說明
	 * int				$debug		是否開啟調試,開啟則輸出sql語句
	 *								0	不開啟
	 *								1	開啟
	 *								2	開啟並終止程序
	 * int				$mode		返回類型
	 *								0	無返回信息
	 *								1	返回執行條目數
	 * string			$table		數據庫表
	 * string/array		$sqlwhere	刪除條件,允許為空,兩種傳值模式
	 *								普通模式:
	 *								'and type = 1 and username like "%os%"'
	 *								數組模式:
	 *								array('type = 1', 'username like "%os%"')
	 */
	public function delete($debug, $mode, $table, $sqlwhere=""){
		//參數處理
		if(is_array($sqlwhere)){
			$sqlwhere = ' and '.implode(' and ', $sqlwhere);
		}
		//數據庫操作
		if($debug === 0){
			if($mode === 1){
				$this->exec("delete from $table where 1=1 $sqlwhere");
				$return = $this->res;
			}else{
				$this->query("delete from $table where 1=1 $sqlwhere");
				$return = NULL;
			}
			return $return;
		}else{
			echo "delete from $table where 1=1 $sqlwhere";
			if($debug === 2){
				exit;
			}
		}
	}
}

  其實使用上,和之前的相差不大,目的就是為了方便移植。

  本次重寫着重處理了幾個問題:

  ① insert語句太復雜,fields與values對應容易出現誤差

  我們看下最常見的一句sql插入語句

insert into tb_member (username, type, dt) values ('test', 1, now())

  在傳統模式下,fields和values參數是分開傳入的,但卻要保證兩者參數傳入的順序一致。這很容易導致順序錯亂或者漏傳某個參數。

  這次已經把問題修改了,采用了mysql獨有的insert語法,同樣是上面那功能,就可以換成這樣的寫法

insert into tb_member set username = "test", type = 1, lastlogindt = now()

  就像update一樣,一目了然。

  ② 部分參數可以用數組代替

  比如這樣一句sql

delete from tb_member where 1=1 and tbid = 1 and username = "hooray"

  在原先調用方法的時候,需要手動拼裝好where條件,這樣操作的成本很高,現在完全可以用這種形式

$where = array(
	'tbid = 1',
	'username = "hooray"'
);
$db->delete(1, 0, 'tb_member', $where);

  條件再多也不會打亂你的思路。同樣,不僅僅是where參數,update里的set也可以以這種形式(具體可參見完整源碼)

$set = array('username = "123"', 'type = 1', 'lastlogindt = now()');
$where = array('tbid = 1');
$db->update(1, 0, 'tb_member', $set, $where);

  ③ 可自定義sql語句

  有時候,sql過於復雜,導致無法使用類里提供的方法去組裝sql語句,這時候就需要一個功能,就是能直接傳入我已經組裝好的sql語句執行,並返回信息。現在,這功能也有了

$db->query('select username, password from tb_member');
$rs = $db->fetchAll();

  是不是很像pdo原生態的寫法?

  ④ 支持創建多數據庫連接

  原先的因為只是數據庫操作方法,所以並不支持多數據庫連接,在實現上需要復制出2個相同的文件,修改部分變量,操作實屬復雜。現在這問題也解決了。

$db_hoorayos_config = array(
	'dsn'=>'mysql:host=localhost;dbname=hoorayos',
	'name'=>'root',
	'password'=>'hooray'
);
$db = new HRDB($db_hoorayos_config);

$db_hoorayos_config2 = array(
	'dsn'=>'mysql:host=localhost;dbname=hoorayos2',
	'name'=>'root',
	'password'=>'hooray'
);
$db2 = new HRDB($db_hoorayos_config2);

  這樣就能同時創建2個數據庫連接,方便處理數據庫與數據庫交互的情況。

  大致新功能就是這么多了,整個代碼並不多,歡迎閱讀了解。下面是我在編寫時寫的測試代碼,也一並提供上來,方便大家學習。

	require_once('global.php');
	require_once('inc/setting.inc.php');
	
	$db = new HRDB($db_hoorayos_config);
	
	echo '<hr><b>select測試</b><hr>';
	echo '普通模式,直接字符串傳入<br>';
	$rs = $db->select(1, 0, 'tb_member', 'username, password', 'and type = 1 and username like "%os%"');
	echo '<br>數組模式,可傳入數組<br>';
	$fields = array('username', 'password');
	$where = array('type = 1', 'username like "%os%"');
	$rs = $db->select(1, 0, 'tb_member', $fields, $where);
	
	echo '<hr><b>insert測試</b><hr>';
	echo '普通模式,直接字符串傳入<br>';
	$db->insert(1, 0, 'tb_member', 'username = "test", type = 1, lastlogindt = now()');
	echo '<br>數組模式,可傳入數組<br>';
	$set = array('username = "test"', 'type = 1', 'lastlogindt = now()');
	$db->insert(1, 0, 'tb_member', $set);
	
	echo '<hr><b>update測試</b><hr>';
	echo '普通模式,直接字符串傳入<br>';
	$db->update(1, 0, 'tb_member', 'username = "123", type = 1, lastlogindt = now()', 'and tbid = 7');
	echo '<br>數組模式,可傳入數組<br>';
	$set = array('username = "123"', 'type = 1', 'lastlogindt = now()');
	$where = array('tbid = 1');
	$db->update(1, 0, 'tb_member', $set, $where);
	
	echo '<hr><b>delete測試</b><hr>';
	echo '普通模式,直接字符串傳入<br>';
	$db->delete(1, 0, 'tb_member', 'and tbid = 1 and username = "hooray"');
	echo '<br>數組模式,可傳入數組<br>';
	$where = array(
		'tbid = 1',
		'username = "hooray"'
	);
	$db->delete(1, 0, 'tb_member', $where);
	
	echo '<hr><b>自定義sql</b><hr>';
	$db->query('select username, password from tb_member');
	$rs = $db->fetchAll();
	var_dump($rs);
	
	$db->close();


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM