PHP Singleton设计模式继承错误

时间:2016-05-10 12:09:03

标签: php oop inheritance design-patterns singleton

来自下面的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()
    {
    }
}

我正在尝试继承新的子类

class SingletonChild extends Singleton {
}

但是当我做测试时

$obj = Singleton::getInstance();
$obj_two = SingletonChild::getInstance();
var_dump($obj === Singleton::getInstance());             // bool(true)
var_dump($obj === $obj_two);   // false

我收到了php致命错误。

  

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

4 个答案:

答案 0 :(得分:4)

您将$instance设为私有,这意味着它无法继承。将其更改为protected

protected static $instance;

本手册讨论了可见性的各个用途

http://php.net/manual/en/language.oop5.visibility.php

所以看起来挂断在你的编辑

$obj = Singleton::getInstance();
$obj_two = SingletonChild::getInstance();
var_dump($obj === $obj_two);   // false

这永远不会成真。 getInstance获取当前类的实例。由于它们是不同的类,它们不一样。然而,做这样的测试是邋。的。我永远不会对这样的物体进行测试。更有意义的是确保您获得Singleton的实例,这样可以非常轻松地完成

if($obj_two instanceof Singleton) // true

因为孩子继承了父母,所以它是父母的实例

答案 1 :(得分:3)

在PHP中继承单例class很困难,在PHP 7.0中是一个事件,但你可以通过对类的一些更改来实现这一点。

首先将Singleton class改为abstract

abstract class Singleton {

}

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

private $instances = [];

现在更改getInstance()方法,如下所示

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

  return self::$instances[static::class];
}

改变你的考试

  

请记住,由于抽象

,您无法致电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

答案 2 :(得分:1)

你应该写: -

if (NULL == self::$instance) {
    self::$instance = new self();
}
return self::$instance;

您不需要创建Singleton类的子类。您可以使用以下语法来获取Singleton类的对象。

 Singleton::getInstance();

只需在任何调用Singleton::getInstance();的类中定义一个方法并返回该对象。

查看this link了解更多详情。

答案 3 :(得分:-1)

单身人士

这是最受欢迎的模式之一。在开发Web应用程序时,从概念上和体系结构上讲,仅允许访问特定类的一个实例(在运行时)通常是有意义的。单例模式使我们能够做到这一点。示例:

    <?php
/**
 * Singleton class
 */
final class Product
{
    /**
     * @var self
     */
    private static $instance;
    /**
     * @var mixed
     */
    public $mix;
    /**
     * Return self instance
     *
     * @return self
     */
    public static function getInstance() {
        if (!(self::$instance instanceof self)) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    private function __construct() {
    }
    private function __clone() {
    }
}
$firstProduct = Product::getInstance();
$secondProduct = Product::getInstance();
$firstProduct->mix = 'test';
$secondProduct->mix = 'example';
print_r($firstProduct->mix);
// example
print_r($secondProduct->mix);
// example