PHP,两个单例继承自一个

问题描述 投票:0回答:1

无法理解如何使单例静态类能够创建不同的单例子类。子类的主要思想是单例的自己的副本。

我有这样的 PdoConnection 类:

class PdoConnection
{
    protected static PDO $dbpdo;

    protected function __construct($mysqlEnv)
    {
        turnDebugMode(false);
        $this->connectPDO($mysqlEnv);
        turnDebugMode(true);
    }

    private function connectPDO(array $mysqlEnv): void
    {
        $dbpdo = new PDO(
            'mysql:host=' . $mysqlEnv['host'] . ';dbname=' . $mysqlEnv['name'] . ';charset=utf8',
            $mysqlEnv['user'],
            $mysqlEnv['pass'],
            [PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4', PDO::MYSQL_ATTR_FOUND_ROWS => true]
        );
        $dbpdo->exec("SET time_zone='+3:00';");

        self::$dbpdo = $dbpdo;
    }

    public static function getPdo(): PDO
    {
        self::createSelf();

        return self::$dbpdo;
    }
}

还有两个继承:

class PdoConnectionApi extends PdoConnection
{
    protected function __construct()
    {
        parent::__construct([
            'host' => '1',
            'name' => '1',
            'user' => '1',
            'pass' => '1',
        ]);
    }

    public static function func1()
    {
    }
}

第二:

class PdoConnectionBot extends PdoConnection
{
    protected function __construct()
    {
        parent::__construct([
            'host' => '2',
            'name' => '2',
            'user' => '2',
            'pass' => '2',
        ]);
    }

    public static function func2()
    {
    }
}

当我尝试为 PdoConnectionApi 或 PdoConnectionBot 创建单例时,主要问题是它只创建一个单例。 附:从示例中删除了单例代码。

php singleton
1个回答
0
投票

这是一个快速的镜头,也许你需要在问题中详细说明一下,但从到目前为止的问题来看,如果我没猜错的话,罪魁祸首是:

      protected static PDO $dbpdo;

具体来说,该属性是静态属性。这仅允许每个类层次结构有一个实例。

您想要的是每个对象层次结构有一个实例,该实例可以是该一个类层次结构的多个实例。

更改、修改基类和更改属性非常简单:

class PdoConnection
{
    # static removed, not a real object property, protected visibility kept.
    protected PDO $dbpdo;

    protected function __construct($mysqlEnv)
    {
        ...
    }

    private function connectPDO(array $mysqlEnv): void
    {
        $dbpdo = new PDO(...);

        ...

        # assignment to the object property
        $this->dbpdo = $dbpdo;
    }

    ...

这应该可以解决问题。您现在可以创建任意数量的单例,它们都有自己的 PDO 实例。

后续步骤:

  • 考虑将类设为抽象,因为其中有模板代码并且您希望对其进行扩展。
  • 考虑将构造函数公开,有一个工厂类知道如何从数组$mysqlEnv创建PDO,然后直接在构造函数中注入一个PDO $dbpdo,并赋值给$this->dbpdo。 (这是对依赖注入的重构,这很可能会解决您创建实例的最初问题。)
© www.soinside.com 2019 - 2024. All rights reserved.