a79146bec5de33353a78c020cbb7d88a22ac2a7f
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / system / SingletonFactory.class.php
1 <?php
2
3 namespace wcf\system;
4
5 use wcf\system\exception\SystemException;
6
7 /**
8 * Base class for singleton factories.
9 *
10 * @author Alexander Ebert
11 * @copyright 2001-2019 WoltLab GmbH
12 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
13 */
14 abstract class SingletonFactory
15 {
16 /**
17 * list of singletons
18 * @var SingletonFactory[]
19 */
20 protected static $__singletonObjects = [];
21
22 /**
23 * Singletons do not support a public constructor. Override init() if
24 * your class needs to initialize components on creation.
25 */
26 final protected function __construct()
27 {
28 $this->init();
29 }
30
31 /**
32 * Called within __construct(), override if necessary.
33 */
34 protected function init()
35 {
36 }
37
38 /**
39 * Object cloning is disallowed.
40 */
41 final protected function __clone()
42 {
43 }
44
45 /**
46 * Object serializing is disallowed.
47 */
48 final public function __sleep()
49 {
50 throw new SystemException('Serializing of Singletons is not allowed');
51 }
52
53 /**
54 * Returns an unique instance of current child class.
55 *
56 * @return static
57 * @throws SystemException
58 */
59 final public static function getInstance()
60 {
61 $className = static::class;
62 if (!isset(self::$__singletonObjects[$className])) {
63 // The previously used `null` value forced us into using `array_key_exists()` which has a bad performance,
64 // especially with the growing list of derived classes that are used today. Saves a few ms on every request.
65 self::$__singletonObjects[$className] = false;
66 self::$__singletonObjects[$className] = new $className();
67 } elseif (self::$__singletonObjects[$className] === false) {
68 throw new SystemException(
69 "Infinite loop detected while trying to retrieve object for '" . $className . "'"
70 );
71 }
72
73 return self::$__singletonObjects[$className];
74 }
75
76 /**
77 * Returns whether this singleton is already initialized.
78 *
79 * @return bool
80 */
81 final public static function isInitialized()
82 {
83 $className = static::class;
84
85 return isset(self::$__singletonObjects[$className]);
86 }
87 }