Wimal Weerawansa Wimal Weerawansa - 6 months ago 19
PHP Question

PHP Singleton design pattern inheritance error

From php singleton class below

<?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()
{
}
}


I am trying to inherit new child class

class SingletonChild extends Singleton {
}


but when I do testing

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


I'm getting php fatal error.


PHP Fatal error: Uncaught Error: Cannot access property
SingletonChild::$instance

Answer

Inheriting Singleton class in PHP is difficult, event in PHP 7.0, but you can do this with some changes on your class to work.

first make your Singleton class to abstract

abstract class Singleton {

}

change your $instance variable to array $instance(s)

private $instances = [];

Now change getInstance() method like below

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

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

And change your test

remember now you can't call Singleton:: getInstance() due to abstract

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
Comments