繼續我的旅程進入更高級的面向對象,我試圖想出能夠創建一個名爲database
的類的最佳方式,該類可以愉快地使用即將被棄用的mysql_
命令,mysqli_
庫和也許還有其他風格的數據庫。OO PHP - 如何創建「通用」數據庫對象?
我想我的調用代碼看起來像這樣,爲了簡單:
$db = new database("MYSQL", $host,$user,$password,$databaseName);
$db->query("SELECT myField FROM myTable");
while ($ROW = $db->fetch_assoc($QRY)) {
echo $ROW['myField'] . "<br/>";
}
當實例數據庫對象,多數民衆贊成在那裏我倒是希望來指定MYSQL,mysqli的,MSSQL的一部分,或無論我以後想添加什麼。
我明白我可以在每database
方法實現switch
塊正是我想要實現:
class database() {
function __construct($type,$host,$user,$password,$databaseName) {
$this->dbType = $type;
switch ($type) {
case "mysql":
mysql_dao::connect($host,$user,$password,$databaseName);
break;
case "mysqli":
mysqli_dao::connect($host,$user,$password,$databaseName);
break;
case "mssql":
mssql_dao::connect($host,$user,$password,$databaseName);
break;
//other cases
}
}
function query($SQL) {
switch ($this->dbType) {
case "mysql": mysql_dao::query($SQL); break;
case "mysqli": mysqli_dao::query($SQL); break;
case "mssql": mssql_dao::query($SQL); break;
}
}
function fetch_assoc($SQL) {
switch ($this->dbType) {
case "mysql": mysql_dao::fetch_assoc($SQL); break;
case "mysqli": mysqli_dao::fetch_assoc($SQL); break;
case "mssql": mssql_dao::fetch_assoc($SQL); break;
}
}
//other methods....
}
...但是這似乎令人難以置信的凌亂。每調用一次database
的方法,代碼就會檢查它是什麼類型,並從另一個對象調用該方法。
所以我的下一個解決方案是簡單地忽略database
可言,只是使用調用代碼看起來像這樣:
$db = new mysql_dao($host,$user,$password,$databaseName);
$db->query("SELECT myField FROM myTable");
while ($ROW = $db->fetch_assoc($QRY)) {
echo $ROW['myField'] . "<br/>";
}
...,所以我們只需要調用數據庫的類型,數據庫訪問對象我們正在使用,但我也不喜歡這個,如果我想把整個項目從mysql轉移到mysqli,我不得不尋找所有這些對象引用並改變它們。雖然在現代PHP編輯器中這是相當微不足道的,但它仍然不覺得它應該是最好的方式(我現在開始變得理論而不實際)
最後,我希望我可以用一個switch語句建立database
類:
class database {
function __construct($type,$host,$user,$pass,$db) {
switch ($type) {
default:
case "MYSQL":
return new mysql_dao($host,$user,$pass,$db);
break;
case "MYSQLI":
return new mysqli_dao($host,$user,$pass,$db);
break;
case "MSSQL":
return new mssql_dao($host,$user,$pass,$db);
break;
}
}
}
...然後只實現與所有的其他方法在類的個人數據庫類型是一個接口。不幸的是,這不起作用,因爲即使database
的構造函數返回另一個對象的實例,我也不能調用database->query
,因爲該方法在數據庫對象中不存在。
至於我可以工作了,與mysql_dao
/mysqli_dao
等類擴展database
是不正確的決定,因爲你必須調用擴展的類來使用它的方法,我想調用父類的,但使用子類的方法。因此,這意味着database
應該擴展dao
類,但你不能有多個潛在的父母一個子類
在結束(可能嗎?) - 我幾乎可以肯定,我失去了一些東西,而我想要的要做的事情應該既可能也很直接,我只是沒有想到正確的方式 - 任何人都可以給我一個指針?
+1對於一個被「必須有更好的方式」驅動的好問題+1。我會考慮一個返回一個代理對象的工廠,然後委託給隱藏在其中的實際對象,但是我又不是PHP程序員。 –
另外請注意,不同的數據庫傾向於支持不同的SQL方言;這可以使它們之間的切換比你期望的更難。 –
@Donal這正是我以這種方式看待它的原因,所以後來的方法如say - selectAllRecords($ table,$ order) - 將能夠以特定數據庫需要寫入的方式編寫SQL。儘管我擔心找到一種方法可以避免在類之外編寫任何SQL(當涉及到複雜的查詢時),但我絕對可以擺脫簡單的東西。 – Codecraft