問題描述
我正在嘗試基于 OOP 設計我的網站,但是我在如何設計數據庫連接方面遇到了麻煩.目前,我正在一個抽象類 Connector 中創建一個私有靜態 PDO 對象.顯然,任何需要與數據庫交互的東西都會擴展這個類.我一直在反復討論如何確保腳本中只有一個連接或 PDO 對象,因為有些頁面將需要多個擴展連接器的類.許多人似乎為此目的推薦單例模式,但我目前的做法似乎可以完成同樣的事情.
I'm attempting to design my website based on OOP, but I'm having trouble with how to design the database connection. Currently, I'm creating a private static PDO object in an abstract class, Connector. Obviously, anything that needs to interact with the database will extend this class. I've been flipping back and forth on how to make sure that there is only ever one connection, or PDO object, in a script because some pages will need more than one class that extends Connector. Many people seem to recommend a Singleton pattern for this purpose, but the way I currently do it seems to accomplish the same thing.
這是我當前的代碼.
abstract class Connector
{
private static $dbh;
public function __construct()
{
try
{
self::$dbh = new PDO(...);
self::$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e)
{
die($e->getMessage());
}
}
public function getDB()
{
return self::$dbh;
}
}
然后任何子類都會像這樣使用它.
Then any subclasses would use it like this.
class Subclass extends Connector
{
public function interactWithDB()
{
$stmt = $this->getDB()->prepare(...);
// etc...
}
}
理論上,我認為子類的每個實例都應該訪問同一個 PDO 實例.這段代碼是否真的有意義,或者我是否以某種方式誤解了靜態屬性?是設計/實踐不好還是單例有更多優勢?
Theoretically, each instance of a subclass should always be accessing the same PDO instance, I think. Does this code actually make sense and or am I misunderstanding static properties somehow? Is it bad design/practice and or does Singleton have more advantages?
如果有什么不清楚的可以評論,謝謝!
Comment if something's not clear, thanks!
Connector 類的存在并不是為了保存 PDO 對象.它的析構函數關閉連接(使其為空)并且它包含諸如 isValueTaken 之類的函數,它檢查一個值是否已經在數據庫中.它有以下抽象函數
The Connector class wasn't meant to exist just to hold the PDO object. It's destructor closes the connection(makes it null) and it contains functions such isValueTaken, which checks if a value is already in the database. It has the following abstract functions
abstract function retrieveData();
abstract function setData();
例如,我有一個擴展連接器的用戶類.它定義了 setData() 來在數據庫中注冊用戶.我不知道這是否會對響應產生影響.
For example I have a User class that extends Connector. It's defines setData() to register a user in the database. I don't know if this makes a difference to the response.
推薦答案
顯然,任何需要與數據庫交互的東西都會擴展這個類.
Obviously, anything that needs to interact with the database will extend this class.
從 OOP 的角度來看,這真的毫無意義.當某個類擴展另一個暗示是"關系的類時.如果你走這條路,你將很難不違反OCPSOLID 中的字母之一.
This really makes no sense from an OOP perspective. When some class extends another class that implies an "is a" relationship. If you go this route you are going to have a hard time not violating OCP which is one of the letters in SOLID.
我一直在反復討論如何確保腳本中只有一個連接或 PDO 對象,因為有些頁面需要不止一個擴展連接器的類.
I've been flipping back and forth on how to make sure that there is only ever one connection, or PDO object, in a script because some pages will need more than one class that extends Connector.
簡單!只需創建一個實例.
Easy! Just create one instance.
許多人似乎為此目的推薦單例模式,但我目前的做法似乎可以完成同樣的事情.
Many people seem to recommend a Singleton pattern for this purpose, but the way I currently do it seems to accomplish the same thing.
很多像這樣的人對 OOP 原則一無所知.使用單例只會引入一個花哨的"全局實例/狀態.
Many people like that have no clue about OOP principles. Using an singleton just introduces a "fancy" global instance / state.
這段代碼是否真的有意義,或者我是否以某種方式誤解了靜態屬性?
Does this code actually make sense and or am I misunderstanding static properties somehow?
說實話更多是對OOP的誤解.
To be honest it is more a misunderstanding of OOP.
這是糟糕的設計/實踐還是單例模式有更多優勢?
Is it bad design/practice and or does Singleton have more advantages?
見上文.
您應該做的(在 OOP 中)是注入數據庫連接需要它.這使您的代碼松散耦合,從而使您的代碼更易于維護、可測試、可調試和靈活.
What you should do (in OOP) is inject the database connection into the classes that need it. This makes your code loosely coupled which in turn makes your code better maintainable, testable, debuggable and flexible.
我也不太明白為什么需要為 pdo 連接創建數據庫類,因為 PDO API 本身已經是 OOP.因此,除非您有真正的理由為 PDO 編寫適配器(可能是這種情況,因為有一些),否則我會放棄它.
Also I don't really see why you need to create a database class for a pdo connection, because the PDO API itself is already OOP. So unless you have a real reason to write a adapter (can be the case, because there are some) for PDO I would just drop it.
我的 0.02 歐元
--
回應您的
Connector 類的存在并不是為了保存 PDO 對象.它的析構函數關閉連接(使其為空).
The Connector class wasn't meant to exist just to hold the PDO object. It's destructor closes the connection(makes it null).
通常根本不需要關閉連接.處理請求后連接將自動關閉(除非我們談論的是持久連接).
There is often no need at all to close the connection. The connection will automatically be closed once the request is handled (unless we are talking about a persistent connection).
并且它包含諸如 isValueTaken 之類的函數,它檢查一個值是否已經存在于數據庫中.它有以下抽象函數
and it contains functions such isValueTaken, which checks if a value is already in the database. It has the following abstract functions
這聽起來像是另一個班級的工作.
That sounds like a job for another class.
例如,我有一個擴展連接器的用戶類.它定義了 setData() 來在數據庫中注冊用戶.我不知道這是否會對響應產生影響.
For example I have a User class that extends Connector. It's defines setData() to register a user in the database. I don't know if this makes a difference to the response.
不,我的觀點仍然成立.用戶不需要從數據庫繼承.這聽起來是不是很奇怪.從數據庫繼承的用戶(我不想見到那個人).如果需要,您應該將數據庫連接注入到用戶中.
No my point still stands. There is no need for a user to inherit from a database. Doesn't that sounds strange. A user inheriting from a database (I don't want to meet that person). You should inject the database connection into the User if it is needed.
這篇關于PHP pdo 實例作為私有靜態屬性的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!