I want to understand that here:

  1. Needed and needed.
  2. Where does this really apply?

Code:

class S { private static $_instance = null; private $_x; public function getX() { return $this->_x; } public function setX($x) { $this->_x = $x; } public static function getInstance() { if (!self::$_instance) { self::$_instance = new self; } return self::$_instance; } private function __construct () { $this->setX(1); } } $s1 = S::getInstance(); $s2 = S::getInstance(); /* вставьте сюда Ваш код создавать новые классы запрещено */ echo $s1->getX(); // должно вывести 1 echo $s2->getX(); // должно вывести 2 
  • Well you, it is a banal combo from Singleton + Registry - Dmitriy Simushev

2 answers 2

The given piece of code is the implementation of the Singleton design pattern.

The Singleton pattern is used in cases when the system allows the use of an object in a single copy. In practice, this can be useful for implementing the Registry template. The classic PHP implementation involves three things:

  1. Implementing a static method for obtaining an instance of Singleton :

     $a = S::getInstance(); 
  2. Private singleton constructor to prohibit the direct creation of instances:

     $a = new S(); // Ошибка 
  3. Private method __clone to prohibit the cloning of singles :

     $a = S::getInstance(); $b = clone $a; // Ошибка 

In the implementation you cited, the third point is omitted, as a result, you can safely use cloning:

 $s1 = S::getInstance(); $s2 = S::getInstance(); $s2 = clone $s1; $s2->setX(2); echo $s1->getX(); // должно вывести 1 echo $s2->getX(); // должно вывести 2 

For reference:

The Registry template is often used if the system needs a centralized storage of any information. It can be like some settings or a set of service objects that are used everywhere. It is not necessary to use a bunch of Single + Registry . It is possible to pass an instance of the Registry explicitly to each class that needs it.

    The private constructor plus the creating function are needed to control the creation of the object. This is essentially the “factory” pattern or one of its varieties. Used, for example, if you want to have several possibilities for initializing an object.

    In this case, the use of creation control is used for a different purpose. The code implements a singleton: the getInstance function getInstance that only one object is created, and each request receives the same object all the time. The private constructor does not allow someone else's code to create its own instance of the object.

    A singleton is needed, for example, if you have an object that must exist only in the singular, (and you don’t want to create it in advance for any reason).


    I don’t know how to make the code output 2 for the second line.

    • one
      You forgot one little thing. Objects can not only be created using the constructor, but also cloned;) - Dmitriy Simushev
    • @DmitriySimushev: Did not know, this is the specificity of PHP, probably? - VladD
    • Hm I did not think that this is a PHP specific feature, but yes, you can clone objects in PHP. It seems that even in C # there was an IClonable interface - Dmitriy Simushev
    • @DmitriySimushev Isn't clone used for PHP cloning? and in the object when cloning there is a method __clone() - Alexey Shimansky
    • one
      @manking: Exactly! But it seems to me that the answer of Dmitriy Simushev deserves to be accepted more. - VladD