【发布时间】:2013-11-19 19:59:26
【问题描述】:
我正在尝试基于 OOP 设计我的网站,但我在如何设计数据库连接方面遇到了麻烦。目前,我正在一个抽象类 Connector 中创建一个私有静态 PDO 对象。显然,任何需要与数据库交互的东西都会扩展这个类。我一直在反复讨论如何确保脚本中只有一个连接或 PDO 对象,因为有些页面需要多个扩展连接器的类。许多人似乎为此目的推荐单例模式,但我目前的做法似乎完成了同样的事情。
这是我当前的代码。
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;
}
}
那么任何子类都会像这样使用它。
class Subclass extends Connector
{
public function interactWithDB()
{
$stmt = $this->getDB()->prepare(...);
// etc...
}
}
我认为,从理论上讲,子类的每个实例都应该始终访问同一个 PDO 实例。这段代码是否真的有意义,或者我是否以某种方式误解了静态属性?是不好的设计/实践,还是 Singleton 有更多的优势?
如果有不清楚的地方请评论,谢谢!
编辑:
连接器类的存在并不是为了保存 PDO 对象。它的析构函数关闭连接(使其为空)并包含诸如 isValueTaken 之类的函数,用于检查数据库中是否已存在值。它具有以下抽象功能
abstract function retrieveData();
abstract function setData();
例如,我有一个扩展连接器的用户类。它定义了 setData() 在数据库中注册用户。我不知道这是否会对响应产生影响。
【问题讨论】:
-
“显然,任何需要与数据库交互的东西都会扩展这个类。” ---一点都不明显。你需要用勺子,你不需要成为勺子,对吗?提示:google 依赖注入和委托。 PS:pimple.sensiolabs.org
-
我建议改用this approach 之类的东西。
-
@zerkms pimple 实现了一个服务提供者,这是另一种反模式。并且服务提供者不是 DI容器。
-
@tereško:周围有任何“真正的”开源 php DI 容器可用吗?
-
@tereško:我确实意识到了不同之处。我可以忍受 sf2 服务容器的“限制”