Intereting Posts
Как проверить, установлен ли мой хостинг-провайдер mod_gzip? Петля через массив PHP, закодированный в JSON Как проверить, является ли строка допустимым именем XML-элемента? Отправить значение текстового поля в PHP MySQL с помощью xcode 8 (Objective-c) с действием или кликом? Передача переменных PHP без использования href в закладках Bootstrap CMS: хранить пользовательские страницы в виде файлов или в базе данных MySQL? php – xml – случайный фильтр и сохранить заказ Что делает этот PHP (function / construct?) И где можно найти дополнительную документацию? Соответствие для нечувствительной к регистру точной фразы с пробелами Использование PHP и RegEx для извлечения всех значений параметров из исходного кода сайта md5 хеширование с использованием пароля как соли? Вывод буфера вывода командной строки PHP независимо от настроек буфера Не удается отправить сеанс cookie – уже отправленные заголовки Как получить данные в функции расширения контроллера? Необычные действия SimpleMODAL OSX в Foreach Loop

Зачем использовать замыкание для назначения вместо прямого назначения значения ключу?

Я смотрел это видео, и в 7:10 он добавляет зависимость db и использует закрытие для назначения значения.

Мой вопрос, почему бы не просто использовать прямое назначение вместо этого, я имею в виду, что не делаю этого:

$container['db'] = $capsule; 

эквивалент этого:

 $container['db'] = function ($container) use ($capsule) { return $capsule; } 

Если нет, какая разница и какой способ лучше?

    Related of "Зачем использовать замыкание для назначения вместо прямого назначения значения ключу?"

    TLDR это потому, что определение зависимостей как закрытий позволяет контейнеру инъекции зависимости создавать их по требованию, поэтому вам не нужно беспокоиться о порядке их определения и управлении их зависимостями вручную.

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

    Если вы напрямую назначаете значение ключу, Pimple вызывает это значение параметра , и когда вам нужно получить доступ к этому ключу, он просто возвращает это точное значение:

     $container['sample-param'] = 'foo'; echo $container['sample-param']; //output: foo 

    Но дело в том, что этот sample-param не требует какой-либо настройки, это просто значение, и мы в порядке с этим. Но предположим, что следующая настройка сервиса:

     $container['myService'] = function($c) { $service = new \Some\Complicated\Service(); //this service depends on cache service $service->setCache($c['cache']); return $service; } $container['cache'] = function($c) { $cache = new \Cache\Driver(); //our cache driver needs a db connection $cache->setDbConnection($c['db']); return $cache; } $container['db'] = function($c) { //our database connection requires some parameters $dbConnection = new \Database\Connection($c['db-config']); return $dbConnection; } $container['db-config'] = [ 'username' => 'foo', 'password' => 'bar', 'host' => 'localhost' ]; //Now we want to user our service: $container['myService']->doSomething(); 

    Пожалуйста, обратите внимание на порядок, который я использовал для определения разных ключей в контейнере.

    myService нужен cache но определение кеша происходит после определения myService. И здесь помогает Pimple, и именно поэтому мы пропускаем контейнер для каждого закрытия, потому что Pimple собирается строить наши зависимости по требованию . Когда нам нужно получить доступ к myService Pimple смотрит на свое внутреннее хранилище данных, если он ранее построил и сохранил myService успешно, он вернет тот же самый экземпляр, иначе он будет называть наше закрытие для его создания. И когда будет вызвано наше закрытие, он попросит Pimple ($ c – контейнер Pimple) дать ему свои зависимости (что в данном случае является службой cache ). Pimple применяет то же самое к кешу, если он еще не построен, он будет строить его и т. Д. … до тех пор, пока он не получит часть, требующую простых параметров, таких как db-config которые немедленно вернутся. И в этой цепочке вызовов замыкания строится наш объект и все его зависимости.

    Теперь представьте, что произойдет, если мы будем использовать простые значения вместо закрытия? В этом случае, когда мы хотим построить myService мы должны заботиться о его зависимостях. Мы должны убедиться, что его зависимости определены до того, как мы определим саму службу, и нам приходится иметь дело с другими проблемами, связанными с управлением зависимостями. В этом случае мы не смогли бы просто определить наш myService и предположить, что имеется доступ к cache , который будет определен позже.

    В этом видео он использует Slim framework для контейнера, который по умолчанию использует Pimple для своего контейнера.

    http://pimple.sensiolabs.org/

    В документации на этой странице упоминается следующее

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

    Сервисы определяются анонимными функциями, которые возвращают экземпляр объекта:

     // define some services $container['session_storage'] = function ($container) { return new SessionStorage('SESSION_ID'); }; $container['session'] = function ($container) { return new Session($container['session_storage']); }; 

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

    По дизайну контейнеры ожидают вызова функции

    Контейнеры Pimple реализуют интерфейс \ArrayAccess (см. Здесь) , а это означает, что они могут заставить объект действовать как массив, но не обязательно быть одним. В исходном коде вы увидите offsetSet и offsetGet , что и происходит, когда вы делаете:

     $container['a'] = function($c){ return new Blah();} $thing = $container['a']; 

    tl; dr Это конкретная вещь контейнера Pimple, а не специфическая для PHP вещь.

    Это совсем другое дело. Первый $container['db'] = $capsule;
    означает, что $container array имеет ключ db и этот ключ равен $capsule , во-вторых, у вас есть $container а ключ db имеет закрытие значения. Вы можете увидеть разницу при сбросе двух результатов:

    Пример закрытия:

     $capsule = 1; $container['db'] = function ($container) use ($capsule) { return $capsule; }; var_dump($container); 

    Результат:

     Array(1) { ["db"]=> object(Closure)#1 (2) { ["static"]=> array(1) { ["capsule"]=> int(1) } ["parameter"]=> array(1) { ["$container"]=> string(10) "<required>" } } } 

    Пример без закрытия:

     $capsule = 1; $container['db'] = $capsule; var_dump($container); 

    Результат:

     result array(1) { ["db"]=> int(1) } 

    Вы можете прочитать о закрытии в руководстве php для лучшего понимания их роли. Руководство по закрытию PHP