Instanceable

Class System\Instanceable it's a synonym for singleton but unlike a singleton, this pattern does not prohibit the creation of new objects of the same class.

Often a project requires the same immutable global instance (object).
If you inherit your class from Instanceable, this will allow you to access the global instance of this class through the static I() method.
In other cases, if necessary, it remains possible to create personal local mutable objects through the constructor (new ...).

class MyClass extends \System\Instanceable {
	public function MyMethod() {}
}

$result1 = MyClass::I()->MyMethod();
$result2 = (new MyClass())->MyMethod();

In the first case, if the global instance has not yet been created, it will be created and called. The advantage of working with a global instance is that it is initialized once on the first call, and later it is available from everywhere. You should not change the internal state of the global instance.

In the second case, a new local object is created that is independent of the global one. It is allowed to change the internal state of local objects.

Many global instances

Very rarely, a project requires many different global instances of the same class.
To organize this, use the only parameter of the static method I(), which is passed as is to the global instance constructor.

class MyUser extends \System\Instanceable {
	public $ID;
	public function __construct($user_id) {
		$this->ID = $user_id;
	}
}

$MyUser456 = MyUser::I(456);
$MyUser457 = MyUser::I(457);

Class override

Very often, you need to override the behavior of some methods of some classes of a third-party kernel (for example, a framework). In this case, you create an overriding successor class and register it in the config (the key is 'redirects'). In the future, all calls to the original global instance will return an instance of a new redefining class, instead of the original.

namespace MySite;

class Engine extends \System\Engine {

	public function Show404() {
		echo '404 not found';
	}

}

global $CONFIG;
$CONFIG = [
	// ...
	'redirects' => [
		'System\Engine' => 'MySite\Engine',
	],
];

// this will return instance of \MySite\Engine:
$Engine = \System\Engine::I();
$Engine->Show404();

Ask question