Ошибка наследования шаблона шаблона PHP 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 :: $ instance

Наследование class Singleton на PHP сложно, событие в PHP 7.0, но вы можете сделать это с некоторыми изменениями в своем классе для работы.

сначала сделайте свой class Singleton abstract

 abstract class Singleton { } 

измените переменную $instance на массив $instance(s)

 private $instances = []; 

Теперь измените метод getInstance() как 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 

Вы сделали $instance private, что означает, что он не может быть унаследован. Измените его на 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 

Поскольку дочерний элемент наследует родителя, это экземпляр родителя

Вы должны написать: –

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

Вам не нужно создавать дочерний класс класса Singleton. Вы можете просто использовать синтаксис ниже для получения объекта класса Singleton.

  Singleton::getInstance(); 

Просто определите метод в любом классе, который вызывает Singleton::getInstance(); и вернуть объект.

Проверьте эту ссылку для получения более подробной информации.