<?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();
и вернуть объект.
Проверьте эту ссылку для получения более подробной информации.