PDO是PHP中一個非常重要的擴展,可以幫助開發者進行數據庫操作。但是,我們也需要注意其關閉的問題。為什么要關閉PDO?
使得PDO主動關閉資源,可以釋放內存并避免數據庫連接數過多導致的問題,同時也可以提高代碼的性能。下面我們來看一些具體的例子:
//不關閉pdo,打開過多長時間會發生什么? $iCount = 0; while(true) { try { $pdo = new PDO('mysql:host=localhost;port=3306;dbname=demo', 'root', '123456'); $PDO->query('SELECT 1'); unset($pdo); } catch(Exception $e) { echo $e->getMessage(); } $iCount ++; echo "Connect DB Count Is {$iCount}\n"; sleep(1); } //關閉pdo try { $pdo = new PDO('mysql:host=localhost;port=3306;dbname=demo', 'root', '123456'); $PDO->setAttribute(PDO::ATTR_PERSISTENT, false); $PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $PDO->setAttribute(PDO::ATTR_EMULATE_PREPARES,false); //禁用模擬 // DO SOMETHING } catch(Exception $e) { echo $e->getMessage(); } finally { $pdo = null; }
上面這個例子,不關閉PDO會一直連著數據庫,系統會產生大量的系統資源,而關閉PDO則可以避免這個問題。
除了釋放內存,關閉PDO還可以預防一種外部攻擊,SQL注入攻擊。
//無預處理 $username = $_GET['username']; $password = $_GET['password']; $conn = new PDO('mysql:host=localhost;dbname=test', 'root', ''); $sql = "SELECT * FROM users WHERE username='$username' AND password='$password'"; $stmt = $conn->query($sql); //有預處理 $username = $_GET['username']; $password = $_GET['password']; $conn = new PDO('mysql:host=localhost;dbname=test', 'root', ''); $sql = "SELECT * FROM users WHERE username=:username AND password=:password"; $stmt = $conn->prepare($sql); $stmt->execute(array(':username' =>$username, ':password' =>$password));
上面這個例子,使用PDO預處理可以使得SQL語句更加安全,避免了SQL注入攻擊對系統的損害。
除此之外,我們還需要額外考慮PDO關閉帶來的一些問題。比如,在數據庫交互過程中意外關閉PDO會導致操作失敗、異常拋出等問題。為了避免這些問題,我們需要通過try-catch-finally來完成PDO的關閉和異常處理:
try { $pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'root', ''); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $statement = $pdo->query('SELECT * from user'); foreach ($statement->fetchAll() as $row) { echo $row['id'] . ' ' . $row['name'] . '
'; } } catch(PDOException $e) { echo $e->getMessage(); } finally { $pdo = null; //PDO關閉 }
總之,關閉PDO的問題是一個需要我們重視的問題。通過保證PDO的關閉,我們可以避免一系列的問題,提高代碼的可維護性和安全性。