Instance
Trait
BlackFox\Instance
adds static methods
Dependency Inversion
Often you need to create a class and its instance (dependent),
which depends on another class or interface (dependency).
For example the class
<?php
class Users {
public function GetByID(int $ID) {
global $MySQL;
return $MySQL->Query("SELECT * FROM users WHERE ID='{$ID}'");
}
}
In a this implementation, the class
- pass the dependency to the constructor of the dependent class in the form of a strongly typed parameter (the type can be a specific class, abstract class or interface)
- save link to dependency in property of dependent class
- use this link to access dependency methods strictly within the contract described in the dependency
<?php
class Users {
/**@var Database $Database */
private $Database;
public function __constructor(Database $Database) {
$this->Database = $Database;
}
public function GetByID(int $ID) {
return $this->Database->Query("SELECT * FROM users WHERE ID='{$ID}'");
}
}
Now the class
But in such an implementation, it is not very convenient to instantiate new instances of the dependent class:
<?php
$Database = new Database();
$Users = new Users($Database);
To simplify the creation of new instances of dependent classes, you can add trait
<?php
class Users {
use \BlackFox\Instance;
// ...
}
Then two static methods
<?php
// make new local instance
$Users = Users::N();
$data = $Users->GetByID(1);
// get (or make and get) global instance
$data = Users::I()->GetByID(1);
This will retain the ability to locally redefine some or all of the dependencies:
<?php
// make another local instance connected to another database
$AnotherUsers = Users::N(['Database' => AnotherDatabase::I()]);
$data = $AnotherUsers->GetByID(1);
::N() - creating a new instance
Static method
<?php
class User {
use \BlackFox\Instance;
public function __construct(Database $Database, int $ID, bool $optional_flag = true) {
$this->Database = $Database;
$this->ID = $ID;
$this->optional_flag = $optional_flag;
}
}
$User1 = User::N(['ID' => 1]); // ok
$User2 = User::N(['ID' => 2, 'optional_flag' => false]); // ok
$User3 = User::N(['ID' => 3, 'Database' => AnotherDatabase::I()]); // ok
$User4 = User::N([]); // error: ID is missing
::I() - return (or create + return) of a global instance
Often a project requires one universal global object (instance), access to which is possible from any part of the code.
The static method once accepts a
one-dimensional dictionary of constructor parameters
as input, creates a global instance of the
appropriate
class (if one has not already been created) and returns a link to it.
Recalling the
Recalling the
<?php
class Database {
use \BlackFox\Instance;
public function __construct(array $params) {}
public function Query($SQL) {}
}
Database::I(['params' => $params]); // ok
Database::I()->Query($SQL1); // ok
Database::I()->Query($SQL2); // ok
Database::I(['params' => $params]); // error
Dictionary of parameters
A one-dimensional dictionary of constructor parameters is optional and is processed as follows:
- If the parameter value is passed, substitutes it
-
If the parameter value is missing:
- If the parameter is optional, substitutes the default value
-
If the parameter is required:
- If the parameter type is absent or is built-in, it throws an error
-
If the parameter type is not built-in (specific class, abstract class, or interface):
- If it is possible to map the type to the global instance, substitutes the link to the global instance as the transmitted value
- Otherwise, it throws an error
The mapping of the user type to the global instance is as follows:
- If there is a key in the global dependency override configuration that describes the relationship between a type and a global instance, use it
- If the type is a specific class, use it
- Otherwise, it throws an error because it cannot find a suitable global instance
Global Override Rules
The current class is considered appropriate unless otherwise specified in the configuration of global override rules.
Global override rules is a dictionary described in the 'overrides' key of the configuration array:
- key -- is a string, the identifier of a specific class, abstract class, or interface which should be redefined
- value -- is a string, identifier of a specific class to be redefined with
<?php
return [
// ...
'overrides' => [
'BlackFox\Engine' => 'Example\Engine',
'BlackFox\Database' => 'BlackFox\MySQL',
'BlackFox\Captcha' => 'BlackFox\CaptchaDriverGoogleRecaptchaV2',
'BlackFox\Users' => 'Example\Users',
'BlackFox\Cache' => 'BlackFox\CacheRedis',
],
// ...
];
BlackFox\Engine::I(); // <-- Example\Engine
BlackFox\Database::I(); // <-- BlackFox\MySQL
BlackFox\Captcha::I(); // <-- BlackFox\CaptchaDriverGoogleRecaptchaV2
BlackFox\Users::I(); // <-- Example\Users
BlackFox\Cache::I(); // <-- BlackFox\CacheRedis
It’s worth noting that these rules are used only by the
Method AddOverrides
Global static method
<?php
\BlackFox\Instance::AddOverrides([
'BlackFox\Cache' => 'BlackFox\CacheRedis',
]);
Ask question