PHP Singleton设计模式继承错误

Wim*_*nsa 7 php oop inheritance singleton design-patterns

从php singleton类下面

<?php
class Singleton
{
    /**
     * @var Singleton The reference to *Singleton* instance of this class
     */
    private static $instance;

    /**
     * Returns the *Singleton* instance of this class.
     *
     * @return Singleton The *Singleton* instance.
     */
    public static function getInstance()
    {
        if (null === static::$instance) {
            static::$instance = new static();
        }

        return static::$instance;
    }

    /**
     * Protected constructor to prevent creating a new instance of the
     * *Singleton* via the `new` operator from outside of this class.
     */
    protected function __construct()
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试继承新的子类

class SingletonChild extends Singleton {
}
Run Code Online (Sandbox Code Playgroud)

但是当我做测试时

$obj = Singleton::getInstance();
$obj_two = SingletonChild::getInstance();
var_dump($obj === Singleton::getInstance());             // bool(true)
var_dump($obj === $obj_two);   // false
Run Code Online (Sandbox Code Playgroud)

我收到php致命错误.

PHP致命错误:未捕获错误:无法访问属性SingletonChild :: $ instance

Kam*_*LIB 3

在 PHP 中继承 Singletonclass很困难,在 PHP 7.0 中也是如此,但是您可以通过对类进行一些更改来实现这一点。

首先让Singleton classabstract

abstract class Singleton {

}
Run Code Online (Sandbox Code Playgroud)

将变量更改$instance为数组$instance(s)

private $instances = [];
Run Code Online (Sandbox Code Playgroud)

现在改变getInstance()方法如下

public static function getInstance() {
  if (!isset(self::$instances[static::class]) {
    self::$instances[static::class] = new static();
  }

  return self::$instances[static::class];
}
Run Code Online (Sandbox Code Playgroud)

并改变你的测试

Singleton:: getInstance()请记住,由于摘要,您现在无法致电

class SingletonChild extends Singleton {
}

class SingletonChildTwo extends SingletonChild {
}

$obj = SingletonChild::getInstance();
$obj_two = SingletonChildTwo::getInstance();
var_dump($obj === SingletonChild::getInstance()); // true
var_dump($obj === $obj_two); // will -> false
Run Code Online (Sandbox Code Playgroud)