Merge pull request #5989 from WoltLab/wsc-rpc-api-const
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / system / SingletonFactory.class.php
CommitLineData
11ade432 1<?php
a9229942 2
11ade432 3namespace wcf\system;
a9229942 4
32baee20 5use wcf\system\exception\SystemException;
11ade432
AE
6
7/**
8aacc17d 8 * Base class for singleton factories.
f341086b 9 *
a9229942
TD
10 * @author Alexander Ebert
11 * @copyright 2001-2019 WoltLab GmbH
12 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
11ade432 13 */
a9229942
TD
14abstract 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 {
0befcb4a 83 $className = static::class;
a9229942
TD
84
85 return isset(self::$__singletonObjects[$className]);
86 }
11ade432 87}