PHP pdo实例作为私有静态属性

sha*_*qb4 3 php database static pdo

我正在尝试基于OOP设计我的网站,但我遇到了如何设计数据库连接的麻烦.目前,我正在抽象类Connector中创建一个私有静态PDO对象.显然,任何需要与数据库交互的东西都会扩展这个类.我一直在翻转如何确保脚本中只有一个连接或PDO对象,因为某些页面需要多个扩展Connector的类.许多人似乎为此目的推荐了Singleton模式,但我目前这样做的方式似乎也完成了同样的事情.

这是我目前的代码.

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后任何子类都会像这样使用它.

class Subclass extends Connector
{
    public function interactWithDB()
    {
        $stmt = $this->getDB()->prepare(...);
        // etc...
    }
}
Run Code Online (Sandbox Code Playgroud)

从理论上讲,我认为子类的每个实例都应该始终访问同一个PDO实例.这段代码是否真的有意义,或者我是否以某种方式误解了静态属性?这是不好的设计/实践,还是Singleton有更多的优势?

如果有什么不清楚的话请评论,谢谢!

编辑:

Connector类并不仅仅是为了保存PDO对象而存在.它的析构函数关闭连接(使其为null)并且它包含isValueTaken等函数,它检查数据库中是否已有值.它具有以下抽象功能

abstract function retrieveData();
abstract function setData();
Run Code Online (Sandbox Code Playgroud)

例如,我有一个扩展Connector的User类.它定义了setData()来在数据库中注册用户.我不知道这是否会对回应产生影响.

Pee*_*Haa 7

显然,任何需要与数据库交互的东西都会扩展这个类.

从OOP的角度来看,这没有任何意义.当某个类扩展另一个暗示"是一个"关系的类时.如果你走这条路线,你将很难不违反OCP,这是SOLID中的一个字母.

我一直在翻转如何确保脚本中只有一个连接或PDO对象,因为某些页面需要多个扩展Connector的类.

简单!只需创建一个实例.

许多人似乎为此目的推荐了Singleton模式,但我目前这样做的方式似乎也完成了同样的事情.

很多人都不喜欢OOP原则.使用单例只会引入一个"奇特"的全局实例/状态.

这段代码是否真的有意义,或者我是否以某种方式误解了静态属性?

说实话,这更多是对OOP的误解.

这是不好的设计/实践,还是Singleton有更多的优势?

往上看.


你应该做什么(在OOP中)是将数据库连接注入需要它的类中.这使您的代码松散耦合,从而使您的代码更易于维护,可测试,可调试和灵活.

另外,我真的不明白为什么需要为pdo连接创建数据库类,因为PDO API本身已经是OOP.因此,除非你有一个真正的理由为PDO写一个适配器(可能是这种情况,因为有一些),我会放弃它.

我的€0.02

-

为了回应您的编辑:

Connector类并不仅仅是为了保存PDO对象而存在.它的析构函数关闭连接(使其为null).

通常根本不需要关闭连接.处理请求后,连接将自动关闭(除非我们讨论的是持久连接).

它包含isValueTaken等函数,用于检查数据库中是否已有值.它具有以下抽象功能

这听起来像是另一堂课的工作.

例如,我有一个扩展Connector的User类.它定义了setData()来在数据库中注册用户.我不知道这是否会对回应产生影响.

不,我的观点仍然存在.用户无需从数据库继承.这听起来不奇怪吗?从数据库继承的用户(我不想见到那个人).如果需要,您应该将数据库连接注入用户.