我正在尝试基于 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模板网!