Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Pimple? Не… Не слышал

Anna | 31.05.2014 | нет комментариев

Удивительно, что на Прогре всё ещё нет статей об этом талантливом DI контейнере для PHP.
Отчего талантливом? Потому, что каждый код этого творения укладывается в 80 строк – небольшой объект с огромными вероятностями.
Контейнер представляет из себя один класс, и его подключение в план выглядит дальнейшим образом:

require_once '/path/to/Pimple.php';

Создание контейнера так же легко:

$container = new Pimple();

Как и многие другие DI контейнеры, Pimple поддерживает два вида данных: сервисы и параметры.

Объявление параметров

Объявить параметры в Pimple дюже легко: используем контейнер как легкой массив:

// Объявляем параметр
$container['cookie_name'] = 'SESSION_ID';
$container['session_storage_class'] = 'SessionStorage';

Объявление сервисов

Сервис — некоторый объект, часть системы, которая исполняет свою определенную задачу.
Скажем, сервисами могут являться: объект, предоставляющий соединение с базой данных, отвечающий за отправку почты, шаблонизацию выводимых данных и т.д.
В Pimple сервисы определяются как неизвестные функции, возвращающие объект обслуживания:

// Объявление сервисов
$container['session_storage'] = function ($c) {
  return new $c['session_storage_class']($c['cookie_name']);
};
$container['session'] = function ($c) {
  return new Session($c['session_storage']);
};

Обратите внимание, что неизвестная функция имеет доступ к нынешнему контейнеру и это разрешает применять в ней другие параметры либо сервисы.
Объекты обслуживания создаются только при обращении к ним, так что порядок объявления не имеет никакого значения.
Пользоваться сделанными сервисами так же легко:

// Приобретение объекта обслуживания
$session = $container['session'];
// Предыдущая строка равносильна дальнейшему коду
// $storage = new SessionStorage('SESSION_ID');
// $session = new Session($storage);

Объявление сервисов «Синглтонов»

По умолчанию при всяком вызове Pimple возвращает новейший объект обслуживания. Если же требуется один экземпляр на всё приложение, всё, что вам нужно сделать – обернуть объявление в способ share():

$container['session'] = $container->share(function ($c) {
  return new Session($c['session_storage']);
});

Объявление функций

Так как Pimple рассматривает все неизвестные функции как объявление сервисов, то для объявления именно функций в контейнере нужно лишь обернуть всё это дело в способ protect():

$container['random'] = $container->protect(function () { return rand(); });

Метаморфоза сервисов позже их объявления

В некоторых случаях может потребоваться метаморфоза поведения теснее объявленного обслуживания. Тогда дозволено применять способ extend() для регистрации добавочного кода, тот, что будет исполнен сразу же позже создания обслуживания:

$container['mail'] = function ($c) {
  return new Zend_Mail();
};
$container['mail'] = $container->extend('mail', function($mail, $c) {
  $mail->setFrom($c['mail.default_from']);
  return $mail;
});

Первым параметром в данную функцию передается имя обслуживания, которое необходимо дополнить, а вторым – функция, принимающая в качестве доводов объект обслуживания и нынешний контейнер. В выводе при обращении к сервису получается объект, возвращаемый данной функцией.
Если же сервис был «Синглтоном», нужно вторично обернуть код дополнения обслуживания способом share(), напротив дополнения будут вызываться всякий раз при обращении к сервису:

$container['twig'] = $container->share(function ($c) {
  return new Twig_Environment($c['twig.loader'], $c['twig.options']);
});
$container['twig'] = $container->share($container->extend('twig', function ($twig, $c) {
  $twig->addExtension(new MyTwigExtension());
  return $twig;
}));

Доступ к функции, возвращающей сервис

Всякий раз, когда вы обращаетесь к сервису, Pimple механически вызывает функцию его объявления. Если же требуется получить прямой доступ именно к функции объявления, дозволено применять способ raw():

$container['session'] = $container->share(function ($c) {
  return new Session($c['session_storage']);
});
$sessionFunction = $container->raw('session');

Повторное применение готового контейнера

Если вы от плана к плану используете одни и те же библиотеки, вы можете сделать готовые контейнеры для повторного применения. Всё, что необходимо сделать – это расширить класс Pimple:

class SomeContainer extends Pimple
{
  public function __construct()
  {
    $this['parameter'] = 'foo';
    $this['object'] = function () { return stdClass(); };
  }
}

И вы можете с лёгкостью применять данный готовый контейнер внутри иного контейнера:

$container = new Pimple();
// Объявление сервисов и параметров основного контейнера
// ...
// Вставка иного контейнера
$container['embedded'] = $container->share(function () { return new SomeContainer(); });
// Конфигурация встроенного контейнера
$container['embedded']['parameter'] = 'bar';
// И его применение
$container['embedded']['object']->...;

Завершение

Управление зависимостями — одна из важнейших и в то же время сложных задач в разработке веб-приложений. Множество фреймворков предлагают личные решения данной задачи. Впрочем в случае применения фреймворков без администратора зависимостей либо проектирования архитектуры приложения без фреймворков, в качестве DI контейнера я бы однозначно предпочел Pimple.

P.S. Примеры применения — перевод официального readme Pimple.

Источник: programmingmaster.ru

Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB