隨著web應(yīng)用程序的發(fā)展,對(duì)于數(shù)據(jù)庫(kù)管理的需求也越來越高。作為一名php程序員,如何優(yōu)化執(zhí)行增刪改查的操作,是必須要解決的問題。而這個(gè)問題的解決,可以通過php封裝數(shù)據(jù)庫(kù)增刪改的類來解決。
1.為什么需要封裝數(shù)據(jù)庫(kù)類?
通常情況下,在進(jìn)行數(shù)據(jù)庫(kù)操作時(shí),我們會(huì)在應(yīng)用程序的主要邏輯中進(jìn)行操作,比如在控制器中操作數(shù)據(jù)庫(kù)。但實(shí)際上,這種方式存在幾個(gè)明顯的問題:
-
代碼冗余:在我們的應(yīng)用程序中,很可能多個(gè)控制器需要對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作。如果每個(gè)控制器都單獨(dú)編寫數(shù)據(jù)庫(kù)操作的代碼,那么就會(huì)出現(xiàn)大量的冗余代碼。
-
代碼可讀性差:這種情況下,代碼的可讀性也就差了。很可能我們同一段代碼就出現(xiàn)在多個(gè)控制器中,這樣一來,就會(huì)給其他開發(fā)人員帶來困擾。
-
安全問題:將數(shù)據(jù)庫(kù)操作代碼直接寫在應(yīng)用程序中,存在一定的安全風(fēng)險(xiǎn)。比如sql注入等問題。
綜上所述,我們有必要將我們的數(shù)據(jù)庫(kù)操作代碼封裝起來,讓它們成為一個(gè)獨(dú)立的模塊。這個(gè)模塊需要具有以下幾個(gè)特點(diǎn):
-
具有良好的可讀性
-
能夠方便的進(jìn)行代碼復(fù)用
-
具有良好的擴(kuò)展性
-
能夠有效的解決安全問題
2.封裝數(shù)據(jù)庫(kù)增刪改類的基本思路
針對(duì)上面提到的問題,我們可以把類寫成php庫(kù)的形式,以便實(shí)現(xiàn)類的復(fù)用。封裝數(shù)據(jù)庫(kù)增刪改類的基本思路如下:
-
將所有的數(shù)據(jù)庫(kù)操作都封裝在一個(gè)類中,比如叫做db類。
-
編寫通用的方法來實(shí)現(xiàn)數(shù)據(jù)庫(kù)增刪改查操作。
-
在方法中實(shí)現(xiàn)參數(shù)化查詢,從而有效的避免sql注入等安全問題。
-
將所有的錯(cuò)誤信息都捕獲,并且封裝成一個(gè)統(tǒng)一的異常拋出給上層代碼。
下面是一個(gè)簡(jiǎn)單的db類的實(shí)現(xiàn):
class db { private $db_host; private $db_user; private $db_pass; private $db_name; private $conn; function __construct($db_host, $db_user, $db_pass, $db_name) { $this->db_host = $db_host; $this->db_user = $db_user; $this->db_pass = $db_pass; $this->db_name = $db_name; } // 數(shù)據(jù)庫(kù)連接方法 function connect() { $this->conn = mysqli_connect($this->db_host, $this->db_user, $this->db_pass, $this->db_name); if (!$this->conn) { throw new Exception('數(shù)據(jù)庫(kù)連接失敗'); } mysqli_query($this->conn, "SET NAMES 'utf8'"); } // 數(shù)據(jù)庫(kù)關(guān)閉方法 function close() { mysqli_close($this->conn); } // 查詢方法,參數(shù)化查詢 function query($sql, $params) { $stmt = mysqli_prepare($this->conn, $sql); if (!$stmt) { throw new Exception('query error: '.mysqli_error($this->conn)); } if (count($params) > 0) { call_user_func_array('mysqli_stmt_bind_param', array_merge(array($stmt, str_repeat('s', count($params))), $params)); } $result = mysqli_stmt_execute($stmt); if (!$result) { throw new Exception('query error: '.mysqli_stmt_error($stmt)); } $rows = array(); $meta = mysqli_stmt_result_metadata($stmt); if ($meta) { while ($field = mysqli_fetch_field($meta)) { $params[] = &$row[$field->name]; } call_user_func_array(array($stmt, 'bind_result'), $params); while (mysqli_stmt_fetch($stmt)) { $rows[] = $row; } } mysqli_stmt_close($stmt); return $rows; } // 增加方法,參數(shù)化查詢 function insert($table, $data) { $sql = 'INSERT INTO '.$table.' ('.implode(',', array_keys($data)).') VALUES ('.implode(',', array_fill(0, count($data), '?')).')'; $result = $this->query($sql, array_values($data)); return mysqli_affected_rows($this->conn); } // 更新方法 function update() { // 實(shí)現(xiàn)更新方法 } // 刪除方法 function delete() { // 實(shí)現(xiàn)刪除方法 } }
3.使用封裝好的類
當(dāng)我們需要對(duì)數(shù)據(jù)庫(kù)進(jìn)行增刪改查時(shí),只需要引入db類,然后實(shí)例化即可。比如:
require_once 'db.php'; $db = new db('localhost', 'root', 'root', 'test'); $db->connect(); $sql = 'INSERT INTO `user`(`name`, `age`) VALUES (?, ?)'; $data = array('Tom', '18'); $db->query($sql, $data); $db->close();
4.總結(jié)
封裝數(shù)據(jù)庫(kù)增刪改的類,是我們?cè)趙eb應(yīng)用程序中必須要完成的任務(wù)。通過將數(shù)據(jù)庫(kù)操作封裝到一個(gè)類中,可以提高代碼的可讀性、可維護(hù)性和安全性,并且還可以方便的進(jìn)行代碼復(fù)用。綜上所述,我們應(yīng)該重視封裝數(shù)據(jù)庫(kù)操作類的開發(fā)。