1
2
3
$container = ABC::newService(ABC::CONTAINER);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Простая упаковка
$callable = function() {
return new \ABC\App\Example;
};
// Так можно предварительно настроить зависимость
$callable = function() use ($paramRorConstruct, $config) {
$example = new \ABC\App\Example($paramRorConstruct);
$example->setConfig($config);
return $example;
};
// Если предварительная настройка не нужна, можно просто использовать имя класса
// Контейнер запакует его автоматически
$container->add('Example', \ABC\App\Example::class);
1 | setMaps() | Устанавливает карты зависимостей |
2 | typeConstruct() | Устанавливает тип внедрения через конструктор |
3 | typeMethodCall() | Устанавливает тип внедрения через сеттеры |
4 | typePropertyes() | Устанавливает тип внедрения через свойства |
5 | add() | Регистрирует сервисы в контейнере |
6 | addGlobal() | Регистрирует в контейнере сервисы с общим доступом |
7 | factory() | Обертка для фабричных сервисов |
8 | addDependence() | Устанавливает зависимости для указанного сервиса |
9 | extendsServices() | Наследует зависимости у указанных сервисов |
10 | addDafault() | Устанавливает общие зависимости |
11 | clearDafault() | Очищает все ранее установленные дефолтные блоки |
12 | get() | Инициализирует и возвращает объект зависимости |
13 | getNew() | Инициализирует и возвращает новый объект зависимости |
14 | has() | Проверяет, есть ли сервис в контейнере |
15 | createLocator() | Создает внутренний сервис-локатор |
16 | bind() | Привязывает к замыканию область видимости |
17 | serviceSynthetic() | Объявляет сервис синтетическим |
18 | isSynthetic() | Проверяет, синтетический сервис или нет |
19 | unsetObject() | Удаляет объект сервиса из хранилища |
Устанавливает карты зависимостей.
Этот метод настраивает контейнер по картам зависимостей. Принимает аргументами карты в виде массивов. Смотри "карта зависимостей"
Смотри еще add(), addGlobal().
public Container::setMaps ( $localMap = [], $globalMap = [] ) | ||
$localMap | array | Карта сервисов и зависимостей, которые будут установлены локально, аналогично методу add(). |
$globalMap | array | Карта сервисов и зависимостей, которые будут установлены с общим доступом из всех инициализированных контейнеров по приципу метода addGlobal() |
return | this |
---|
Устанавливает тип внедрения зависимостей через конструктор
Этим методом можно настроить контейнер так, что он будет внедрять зависимости через конструктор. Этот тип внедрения установлен по умолчанию. Если ранее контейнер был настроен на другой тип, можно установить тип внедрения через конструктор для отдельных сервисов, для этого нужно перечислить их в параметрах, либо задать массивом.
Смотри пример
public Container::typeConstruct ( ...$services ) | ||
$source | array|boolean | Массив, в котором указаны сервисы, для которых выбран тип внедрения через сеттеры. Можно указать сервисы не массивом, а аргументами. Если передать true, этот тип будет установлен для всех сервисов. |
return | this |
---|
Устанавливает тип внедрения зависимостей через сеттеры
Этим методом можно настроить контейнер так, что он будет внедрять зависимости через сеттеры. Для всех сервисов нужно передать параметром true. Можно установить этот тип для отдельных сервисов, для этого нужно перечислить их в параметрах, либо задать массивом.
Смотри пример
public Container::typeMethodCall ( ...$services ) | ||
$source | array|boolean | Массив, в котором указаны сервисы, для которых выбран тип внедрения через сеттеры. Можно указать сервисы не массивом, а аргументами. Если передать true, этот тип будет установлен для всех сервисов. |
return | this |
---|
Устанавливает тип внедрения зависимостей через публичные свойства
Этим методом можно настроить контейнер так, что он будет внедрять зависимости через публичные свойства. Для всех сервисов нужно передать параметром true. Можно установить этот тип для отдельных сервисов, для этого нужно перечислить их в параметрах, либо задать массивом.
Смотри пример
public Container::typePropertyes ( ...$services ) | ||
$source | array|boolean | Массив, в котором указаны сервисы, для которых выбран тип внедрения через сеттеры. Можно указать сервисы не массивом, а аргументами. Если передать true, этот тип будет установлен для всех сервисов. |
return | this |
---|
Помещает сервис в контейнер.
Этот
метод записывает в хранилище анонимную функцию под уникальным идентификатором. В теле функции происходит инициализация класса
сервиса.
Если передать вторым аргументом имя класса, он будет упакован в замыкание автоматически.
Смотри пример
Смотри еще setMaps(), addGlobal().
public Container::add ( $service, $source = null ) | ||
$source | string|string | Идентификатор сервиса, либо карта зависимостй. Сервисы будут установлены локально. |
$source | callable|string|object | Замыкание, в котором упакована инициализация объекта, либо имя класса, либо объект сервиса. |
return | this |
---|
Помещает в хранилище сервис с общим доступом
Этот
метод записывает в хранилище анонимную функцию под уникальным идентификатором по принципу "синглтон". Этот сервис будет доступен во всех экземплярах контейнера.
Если передать вторым аргументом имя класса, он будет упакован в замыкание автоматически.
Смотри пример
public Container::addGlobal ( $services, $source = null ) | ||
$source | string|string | Идентификатор сервиса, либо карта зависимостй. Сервисы будут установлены глобально, по принципу Singlton. |
$source | callable|string|object | Замыкание, в котором упакована инициализация объекта, либо имя класса, либо объект сервиса. |
return | this |
---|
Обертка источника данных для сервиса
По умолчанию метод get() возвращает один и тот же инстанс класса (объект). Но бывают случаи, когда нужно возвращать всегда новый. И хотя есть метод getNew(), который это делает, можно задать эту опцию при регистрации сервисов. Нужно просто обернуть источник этим методом.
Смотри пример
public Container::factory ( $source, $source = null ) | ||
$source | mix | Источник данных для регистрируемого сервиса |
return | callable | Замыкание, в котором упакован источник данных |
---|
Устанавливает зависимости, которые будут внедрены в сервис.
Выбирает по идентификатору из хранилища сервис и внедряет в него зависимости. Для каждого сервиса инициализируется новый объект зависимости, если она не зарегистрирована как сервис.
public Container::addDependence ( $serviceId, $dependences ) | ||
$serviceId | string | Сервис-реципиент, в который будет помещены зависимости. |
$dependences | array | Массив, состоящий из пар property => dependence. Смотри примеры. |
return | this |
---|
Наследует зависимости у указанных сервисов.
Чтобы избежать повторов кода, можно унаследовать ранее установленные зависимости. Для этого нужно задать параметрами те сервисы, зависимости которых требуются в устанавливаемом сервисе. Метод можно вызвать только после установки сервиса методами add() и addGlobal()
Если сервисы не наследуются на стороне PHP, то в реципиенте должны быть реализованы сеттеры для наследуемых зависимостей.
Зависимости, устанавливаемые для сервиса методом addDependence() перезапишут унаследованные этим методом.
public Container::extendsServices ( ...$services) | ||
$services | string | Сервисы, зависимости которых будут внедрены в текущий сервис. |
return | this |
---|
Устанавливает общие зависимости для всех сервисов, помещенных в контейнер.
Зависимости, установленные этим методом автоматически будут применены ко всем сервисам контейнера. Зависимости, устанавливаемые для отдельного сервиса методом addDependence() перезапишут дефолтные. Смотри пример
public Container::addDafault ( $dependances ) | ||
$dependances | array | Массив зависимостей в виде пар property => callable. Смотри пример |
return | this |
---|
Очищает все ранее установленные дефолтные блоки.
Этим методом можно удалить все общие зависимости, установленные раньше. Дальше можно установить новый дефолтный блок. Смотри пример
public Container::clearDafault ( ) | ||
return | this |
---|
Инициализирует и возвращает объект зависимости.
Находит по идентификатору и возвращает объект зависимости. Если сервис был упакован в контейнер, как shared, то возвращается один и тот же объект по принципу "синглтон". Если он упакован обычно, то каждый раз возвращается новый объект.
Смотри еще getNew().
public Container::get ( $serviceId ) | ||
$serviceId | string | Идентификатор сервиса в контейнере. |
return | object | Объект сeрвиса |
---|
Инициализирует и возвращает новый объект зависимости.
Возвращает по идентификатору сервиса новый объект, вне зависимости от того, как он был упакован.
Смотри еще get().
public Container::getNew ( $serviceId ) | ||
$serviceId | string | Идентификатор сервиса в контейнере. |
return | object | Объект сeрвиса |
---|
Проверяет, есть ли сервис в контейнере.
Возвращает булево значение в зависимости от того, есть ли в контейнере сервис с таким идентификатором.
public Container::has ( $serviceId ) | ||
$serviceId | string | Идентификатор зависимости в контейнере. |
return | boolean | true, если есть, false, если нет. |
---|
Устанавливает внутренний сервис-локатор.
Локализует указанные сервисы в отдельный контейнер, который можно использовать как зависимость.
public Container::createLocator ( $locatorId, ...$services ) | ||
$locatorId | string | Идентификатор локатора в контейнере. |
$services | array|string | Массив карты зависимостей, либо перечень идентификаторов сервисов, которые будут локализованы в локаторе |
return | object | this |
---|
Присваивает замыканию новую область видимости.
По умолчанию область видимости всех замыканий контейнера, это объект самого контейнера. Этот метод позволяет присвоить новую область.
public Container::bind ( $callable, $newthis ) | ||
$callable | callable | Замыкание, которому присваивается новая область видимости |
$newthis | object | Новая область видимости |
return | callable | Продублированное замыкание с новой областью видимости |
---|
Объявляет сервис синтетическим.
Если объявить сервис синтетическим, в него будет запрещено внедрение зависимости.
public Container::serviceSynthetic ( $serviceId ) | ||
$serviceId | string | Идентификатор зависимости в контейнере. |
return | void |
---|
Проверяет, объявлен ли сервис синтетическим.
Если сервис объявлен синтетическим, в него запрещено внедрение зависимости. Проверить это помогает данный метод.
public Container::isSynthetic ( $serviceId ) | ||
$serviceId | string | Идентификатор зависимости в контейнере. |
return | boolean | true, если сервис синтетический, false, если нет. |
---|
Удаляет объект сервиса из хранилища.
Иногда нужно, что бы отработал деструктор сервиса. Но так, как объект хранится в контейнере, обычным unset() вызвать его не получится. Для этой цели и служит данный метод. При этом сервис остается в контейнере и может быть повторно вызван.
public Container::unsetObject ( $serviceId ) | ||
$serviceId | string | Идентификатор зависимости в контейнере. |
return | void |
---|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Класс для проверки
class MyClass
{
protected $time;
public function checkTime()
{
if (empty($this->time)) {
$this->time = microtime(true);
}
return $this->time;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
// Помещаем класс MyClass в контейнер в виде анонимной функции
$container->add('MyClass',
function() {
return new MyClass;
}
);
// То же самое, под другим идентификатором, используя имя класса
$container->add('Other', MyClass::class);
// Или можно сразу объект, если есть необходимость
$container->add('Another', new MyClass);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Помещаем класс MyClass в контейнер, используя имя класса
$container->add('MyClass', MyClass::class);
// Так можно достать
$obj = $container->get('MyClass');
echo $obj->checkTime(); // .....10.201
echo '<br>';
sleep(1);
// Метод get() всегда возвращает один и тот же объект
// по принципу Singlton
$obj = $container->get('MyClass');
echo $obj->checkTime(); // .....10.201
echo '<br>';
// Это новый объект
$obj = $container->getNew('MyClass');
echo $obj->checkTime(); // .....11.208
echo '<br>';
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Заворачиваем имя класса в фабричную обертуку
$container->add('MyClass', $container->factory(MyClass::class));
$obj = $container->get('MyClass');
echo $obj->checkTime(); // .....82.3049
echo '<br>';
sleep(1);
// Теперь метод get() будет возвращать новые объекты
// по принципу Singlton
$obj = $container->get('MyClass');
echo $obj->checkTime(); // .....82.3194
echo '<br>';
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Получаем контейнер
$container = ABC::newService(ABC::CONTAINER);
// Помещаем класс MyClass в контейнер, используя имя класса
$container->addGlobal('MyClass', MyClass::class);
// Смотрим.
$obj = $container->get('MyClass');
echo $obj->checkTime(); // .....10.201
echo '<br>';
// Инициализируем второй контейнер
$container = ABC::newService(ABC::CONTAINER);
// Можно получить сервис из первого.
$obj = $container->get('MyClass');
echo $obj->checkTime(); // .....10.201
echo '<br>';
1
2
3
4
5
6
7
8
9
10
11
12
13
class Recepient
{
protected $example;
protected $std;
public function __construct(Example $example, StdClass $std)
{
$this->example = $example;
$this->std = $std;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Recepient
{
protected $example;
protected $std;
// Простой сеттер
public function setExample(Example $example)
{
$this->example = $example;
}
// Сеттер с проверкой
public function setStd(StdClass $std)
{
if(empty($this->std)){
$this->std = $std;
}
}
}
1
2
3
4
5
6
7
class Recepient
{
public $example;
public $std;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// Класс-реципиент
class Recepient
{
protected $example;
protected $std;
public function __construct(Example $example, \StdClass $std)
{
$this->example = $example;
$this->std = $std;
}
public function run()
{
$this->example->display();
}
}
// Класс-зависимость
class Example
{
public function display()
{
echo 'Я Example!';
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Создаем сервис
$container->add('Recepient', Recepient::class);
// Добавляем зависимости для класса Recepient
$container->addDependences('Recepient', [ // по имени класса
'example' => Example::class,
// с использованием замыкания
'std' => function(){
return new \StdClass;
}
]);
//
$obj = $container->get('Recepient');
$obj->run(); // Я Example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Регистрируем зависимости как сервисы
$container->add('Example', Example::class);
$container->add('Std', \StdClass::class);
// Создаем сервис Recepient
$container->add('Recepient', Recepient::class);
// Внедряем сервисы как зависимости
$container->addDependences('Recepient', [
'example' => 'Example',
'std' => 'Std'
]);
// Смотрим
$obj = $container->get('Recepient');
$obj->run(); // Я Example!
Что бы не возникло неоднозначности после внедрения зависимости, сервис в контейнере автоматически объявляется синтетическим. И дальнейшее внедрение в него запрещено.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Устанавливаем общие зависимости
$container->addDefault([
'example' => Example::class,
'std' => \stdClass::class
]);
// Создаем сервис
$container->add('Recepient', Recepient::class);
// Смотрим
$obj = $container->get('Recepient');
$obj->run(); // Я Example!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Устанавливаем общие зависимости
$container->addDefault([
'example' => Example::class,
'std' => \stdClass::class
]);
// Создаем сервис
$container->add('Recepient', Recepient::class);
// Отменяем одну зависимость для сервиса Recepient
$container->addDependences('Recepient', [
'std' => false
]);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Устанавливаем общие зависимости
$container->addDefault([
'example' => Example::class,
'std' => \stdClass::class
]);
// Создаем сервис
$container->add('Recepient', Recepient::class);
// Смотрим
$obj = $container->get('Recepient');
$obj->run(); // Я Example!
// Очищаем дефолтный блок
$container->clearDefault();
// Создаем другой сервис в котором уже нет дефолтных зависимостей
$container->add('OtherRecepient', Recepient::class);
// Смотрим
$obj = $container->get('OtherRecepient');
$obj->run(); // Too few arguments to function Recepient::__construct()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Создаем сервис с зависимостью
$container->add('Recepient', Recepient::class)
->addDependences('Recepient', [
'example' => Example::class,
'std' => \stdClass::class
]);
// Создаем другой сервис и наследуем зависимости от первого
$container->add('OtherRecepient', Recepient::class )
->extendsServices('Recepient');
// Смотрим
$obj = $container->get('OtherRecepient');
$obj->run(); // Я Example!
1
2
3
4
5
// Наследуем зависимости от двух сервисов: Recepient и SomeService
$container->add('OtherRecepient', Recepient::class )
->extendsServices('Recepient', 'SomeService');
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Класс-реципиент
class Recepient
{
protected $locator;
public function __construct(ContainerInterface $locator)
{
$this->locator = $locator;
}
public function run()
{
$example = $this->locator->get('Example');
$example->display();
// Этот код вызовет исключение, если сервис Recepient
// не зарегистрирован в локаторе
// $example = $this->locator->get('Recepient');
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Регистрируем зависимость как сервис
$container->add('Example', Example::class);
// Генерируем локатор и помещаем сервис в него
$container->createLocator('Locator', 'Example');
// Регистрируем основной сервис и передаем в него зависимостью локатор
$container->add('Recepient', Recepient::class)
->addDependences('Recepient', ['locator' => 'Locator']);
// Запускаем
$obj = $container->get('Recepient'); // Я Example!
$obj->run();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// Класс-реципиент
class Recepient
{
protected $example;
protected $std;
public function __construct(Example $example, StdClass $std)
{
$this->example = $example;
$this->std = $std;
}
public function run()
{
$this->example->display();
}
public function __destruct()
{
echo '<br>Вызван деструктор';
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Создаем глобальный сервис
$container->addGlobal('Recepient', Recepient::class)
->addDependences('Recepient', [
'example' => Example::class,
'std' => \stdClass::class
]);
// Объявляем сервис синтетическим
$container->serviceSynthetic('Recepient');
// Проверяем
var_dump($container->isSynthetic('Recepient')); // true
// Получаем объект сервиса
$obj = $container->get('Recepient');
// Уничтожаем объект в скрипте
unset($obj);
// Уничтожаем объект в контейнере
$container->unsetObject('Recepient'); // Вызван деструктор
echo '<br>Продолжение скрипта<br>';
$obj = $container->get('Recepient');
$obj->run(); // Я Example!
// Вызван деструктор
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$map = [
'Recepient' => [
// Элемент без строкового ключа, это класс сервиса
Recepient::class,
// Простое внедрение зависимости
'example' => Example::class,
// Упаковка зависимости в замыкание
'std' => function(){
return new \StdClass;
}
],
];
// Устанавливаем карту в контейнер
$container->setMaps($map);
$obj = $container->get('Recepient');
$obj->run(); // Я Example!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$map = [
// Регистрируем сервисы
'Example' => Example::class,
'Std' => function(){
return new \StdClass;
},
'Recepient' => [
Recepient::class,
// Внедряем их зависимостями
'example' => 'Example',
'std' => 'Std'
],
];
// Можно установить карту с помощью метода add()
$container->add($map);
$obj = $container->get('Recepient');
$obj->run(); // Я Example!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$map = [
'__default' => [
'example' => Example::class,
'std' => function(){
return new \StdClass;
}
],
'Recepient' => Recepient::class,
];
$container->add($map);
// Запускаем
$obj = $container->get('Recepient');
$obj->run(); // Я Example!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$map = [
// Регистрируем сервис с зависимостями
'Service' => [
Recepient::class,
'example' => Example::class,
'std' => function(){
return new \StdClass;
}
],
// Наследуем от него зависимости
'Recepient extends Service' => Recepient::class,
];
$container->add($map);
// Запускаем
$obj = $container->get('Recepient');
$obj->run(); // Я Example!