似乎有兩個主要問題,導致人們在課堂中包裝PDO代碼。
首先是需要調用數據庫一次並重用數據庫連接。例如,您不希望在每個Model函數內調用數據庫,因爲它會生成太多的數據庫連接,通常連接的數量會超過數據庫服務器允許的數量。
接下來是要阻止必須將數據庫連接變量(例如,$conn
)傳遞給函數。 這可以通過示例來說明,因爲'select($ table,$ where)'優於'select($ conn,$ table,$ where)'。
有幾個微框架/類/庫爲你做這個。 一些較好的有:
或 - 通常 - 這是如何完成的?
就我個人而言,我更喜歡使用「幾乎」普通PDO調用的程序代碼(使用全局$ dbh變量來保存數據庫連接)。
要做到這一點,我先建一個DB()函數來存放數據庫連接:
function db($dsn=null)
{
global $dbh;
if(isset($dbh)) {
return $dbh;
} else {
$dbh = new PDO($dsn);
$dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $dbh;
}
}
用法:
db("sqlite:articles.db");
$stmt = db()->prepare("INSERT INTO `article` (`id`,`title`,`body`) VALUES (:id, :title, :body)");
$stmt->execute([ ':id'=>$id, ':title'=>$title, ':body'=>$body ]);
或者:
$stmt = db()->prepare("SELECT * FROM `article` WHERE `id`=:id");
$stmt->execute([':id'=>542]);
$row = $stmt->fetch(PDO::FETCH_OBJ);
echo $row->id;
...
它甚至作品在函數內允許我使用簡單的語法創建我自己的模型函數:
db("sqlite:articles.db");
print_r(select_article("542"));
function select_article($id) {
// Note that we use db() inside the function, without adding a $conn variable
$stmt = db()->prepare("SELECT * FROM `article` WHERE `id`=:id AND published=1");
$stmt->execute([':id'=>$id]);
return $stmt->fetch(PDO::FETCH_ASSOC);
}
function insert($table,$data) {
...
$stmt = db()->prepare("INSERT INTO `article` (`id`,`title`,`body`) VALUES (:id, :title, :body)");
$stmt->execute([ ':id'=>$id, ':title'=>$title, ':body'=>$body ]);
}
謝謝你的回答。正如我所看到的,所以我無法使用我已有的數據庫連接,並且不得不爲此類和其他靜態類再次使用它。 – Haudegen
如果你已經有了一個數據庫連接並且想要重用它,那麼你必須將它注入到某個地方的類中,你可以隱式地或顯式地將它注入。我已經更新了答案以反映這一點。問候, –