Pull to refresh

IoC на PHP

PHP *
Inversion of Control (IoC) контейнеры — это удобный способ организации внедрения зависимости получивший широкое применение в мире Java.

Данная библиотека позволяет использовать IoC контейнеры в PHP.



Для примера опишем несколько интерфейсов:

interface First {
    public function first();
}

interface Second {
    public function second();
}

interface Third {
    public function third();
}


И их реализаций:

class Foo implements First {
    public function first() { /* ... */ }
}

class Boo implements Second {
    public function __construct(First $first) { /* ... */ }

    public function second() { /* ... */ }
}

class Woo implements Third {
    public function __construct(First $first, Second $first) { /* ... */ }

    public function third() { /* ... */ }
}


Теперь воспользуемся IoC контейнером для описания зависимостей:

$ioc = IoC\Container::getInstance();

$ioc->register('Foo');
$ioc->register('Boo');
$ioc->register('Woo');


Зависимости назначаются автоматически. Класс Foo реализует интерфейс First: в IoC контейнере First ссылается на Foo.

Опишем класс-менеджер зависящий от этих интерфейсов:

class Manager
{
    use IoC\Creatable;

    public function __construct(First $first,
                                Second $second,
                                Third $third)
    {
        /* ... */
    }
}


Создадим экземпляр менеджера:

$manager = Manager::create();


IoC сам создаст экземпляры нужных классов для конструктора менеджера.

Если нет PHP 5.4, то можно не использовать примеси:

class Manager
{
    public static function create()
    {
        return \IoC\Factory::create(get_called_class(), func_get_args());
    }

    /* ... */
}


Так же в конструкторе менеджера можно описать дополнительные параметры:

class Manager
{
    use IoC\Creatable;

    public function __construct(First $first,
                                Second $second,
                                Third $third,
                                $value,
                                $anotherValue = 'default')
    {
        /* ... */
    }
}


И по прежнему пользоваться IoC:

$manager = Manager::create('value', 'another value');
$managerWithDefault = Manager::create('value');


В библиотеке реализованы три типа зависимости: Reference, Lazy и Prototype.

Ленивая загрузка:
$ioc->register('Foo');

Экземпляр класса Foo будет создан только при вызове функции create()

В данном случае, везде будет использован один экземпляр класса Foo:
$ioc->register(new Foo());


Если класс построен на шаблоне прототип (новые объекты создаются при помощи clone), то полезной будет следующая функция:
$ioc->prototype(new Foo());

При каждом вызове create() будет создан новый экземпляр Foo при помощи clone.

Так же можно добавлять свои ассоциации:
$ioc->assoc(new MyAssoc('Foo'));


IoC позволяет вручную настроит соответствие реализации интерфейсу:

$ioc->register('Foo', 'First');

$ioc->register(new Foo(), 'Second');

$ioc->prototype('Foo', 'First');


Множественная ассоциация. В случае если класс FooBoo реализует сразу два интерфейса First, Second:

$ioc->register('FooBoo', array('First', 'Second'));


Так же можно добавить ассоциации для классов:

// Если Boo extends Foo
$ioc->register('Boo', 'Foo');


Проект на GitHub

Другие реализации IoC для PHP

PHP порт Pico Container
Phemto
Sharbat
Tags:
Hubs:
Total votes 44: ↑33 and ↓11 +22
Views 14K
Comments Comments 120