2013-02-14 3 views
6

Я только что начал изучать Zend Framework 2 как долгое время разработчиком Zend Framework 1. У меня небольшие проблемы, обволакивающие новую терминологию.Zend Framework 2 - Приложения/Модули/Менеджеры обслуживания - Oh My

Назад в ZF1, если бы я хотел создать регистратор, который был глобальным для приложения, я бы добавил конфигурацию в файл application.ini, и bootstrap инициализировал бы его как ресурс (я надеюсь, что я говорю это правильно) , Итак, с любого из моих модулей-контроллеров я мог получить доступ к регистратору через ресурсы начальной загрузки.

Ввод ZF2. Модули - это немного другое зверь, они автономны, но я немного смущен тем, как они взаимодействуют с приложением. Мне кажется, что именно здесь запускается ServiceManager. Моя цель состоит в том, чтобы мой модуль (а не контроллер, но сам модуль), чтобы проверить, определил ли приложение логгер, и если он есть, используйте этот регистратор во всем модуле. Если приложение не определяет регистратор, я хочу, чтобы модуль определял регистратор для ведения журнала по модулю.

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

Примечание: Я прошел через Quickstart Роба Аллена (достаточно информации и единственный ресурс, который я нашел, который не имеет темной тени), и ZF2 (readthedocs), и googled tons уже. То, что я нахожу, состоит в том, что информация, как правило, очень неясна, когда дело доходит до «где» некоторые части головоломки.

ответ

6

Что вы знаете о Zend Framework 1.x - это «Ресурс приложения».

Понятие «приложения ресурса» заменяется в Zend Framework 2, так называемые "services" (интро here)

другое изменение является сами модули. В ZF1 модуль был главным образом подразделением вашего приложения, которое обрабатывало некоторые запросы. Это больше не относится к ZF2: если ваш модуль определяет службу или контроллер, этот доступ теперь доступен для всего приложения. Есть хорошее введение на некоторых differences between ZF1 and ZF2 by Gary Hockin.

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

Для вашего конкретного случая регистратора я предлагаю, чтобы ваш модуль всегда определял регистратор и потребляет его. Что можно сделать, чтобы определить регистратора условно имеет следующий вид:

class MyModule 
{ 
    public function onBootstrap($e) 
    { 
     // $e->getTarget() is the \Zend\Mvc\Application 
     $sm = $e->getTarget()->getServiceManager(); 

     if (!$sm->has('some-logger-name')) { 
      $sm->setFactory('some-logger-name', function ($sl) { 
       return new MyLogger($sl->get('some-db')); 
      }); 
     } 
    } 
} 

Вы бы тогда быть в состоянии использовать «некоторый регистратор-имя» ваш по всей вашей заявке.

Другой подход просто определить регистратора услуг и пусть другие модули или конфигурации заменить его позже:

class MyModule 
{ 
    public function getConfig() 
    { 
     return array(
      'service_manager' => array(
       'factories' => array(
        'some-logger-name' => 'My\Logger\Factory\ClassName' 
       ), 
      ), 
     ); 
    } 
} 

То же самое достигается с getServiceConfig, который является менее гибким и не может быть в кэше, но имеет более высокую приоритет над getConfig (позволяет переопределение) и позволяет также определять сервисные заводы, как закрытие:

class MyModule 
{ 
    public function getServiceConfig() 
    { 
     return array(
      'factories' => array(
       'some-logger-name' => function ($sl) { 
        return new MyLogger($sl->get('some-db')); 
       }, 
      ), 
     ); 
    } 
} 

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

Концепция с модулями и конфигурациями заключается в том, что «последний модуль выигрывает», поэтому вы можете определить услугу 'some-logger-name' либо в своем модуле, либо в любом загруженном перед ним модуле.

Эти же концепции применяются также к вашему соединению с БД.

Как вы можете видеть, переезд в службы уже дал вам определенную степень свободы.

Имейте в виду, что это не означает, что «Приложение» что-то определяет для вас: модули определяют ваши службы/конфиги/события и т. Д. Запуск приложения - это совокупность всех этих вещей вместе.

+0

Я высоко ценю рецензию (и быстро взглянул на ссылку, которую вы предоставили, я рассмотрю ее подробно чуть позже). Из-за той борьбы, которую я получил (частично отмеченный в предыдущем вопросе), я также начал читать исходный код ZF2, чтобы лучше понять рабочий процесс. Ваш ответ очень хорошо объяснен в сочетании с чтением исходного кода, я начинаю лучше понимать, как фигуры подходят друг к другу. Я с нетерпением жду прочитанной (ссылки), которую вы предоставили, так как быстро взглянул, как будто мне нужно переходить с ZF1 на ZF2! –

+0

Учитывая, как новый выпуск ZF2, а также объем изменений в процессе управления, управляемый/управляемый событиями, в информации, доступной до сих пор (по крайней мере, из того, с чем я столкнулся), существует огромное количество неизвестности, я очень цените ссылку, которую вы предоставили, поскольку она, похоже, хорошо описывает переход. –

+0

@AaronMurray мастер 'ServiceManager' и' EventManager', и все будет выглядеть намного проще. – Ocramius

3

Я думаю, особенно в случае регистрации, есть, возможно, даже лучше, конечно, более инкапсулированный путь, чем использование ServiceManager. ZF2 по существу представляет собой платформу, управляемую событиями, и функциональность, которая позволяет использовать эту архитектуру, управляемую событиями, в наших интересах. Для этого идеальный пример. Вместо того, чтобы определять фабрику, вы должны присоединить событие регистрации, которое может быть запущено из любого места приложения.

Приложить слушатель log событий в вашем Module.php:

public function onBootstrap(MvcEvent $e) 
{ 
    //setup some $logger 

    $sharedManager = $e->getApplication()->getEventManager()->getSharedManager(); 

    $sharedManager->attach('*', 'log', function($e) use ($logger) { 
     /** @var $e MvcEvent */ 
     $target = get_class($e->getTarget()); 
     $message = $e->getParam('message', 'No message provided'); 
     $priority = $e->getParam('priority', Logger::INFO); 
     $message = sprintf('%s: %s', $target, $message); 
     $logger->log($priority, $message); 
    }); 
} 

Затем запустить его из везде в приложении, например, контроллер:

$this->getEventManager()->trigger('log', $this, array(
    'priority' => \Zend\Log\Logger::INFO, 
    'message' => 'just some info to be logged' 
)); 
+0

Речь идет не о том, что во всем модуле имеется «регистратор», но в основном объясняется, как вы используете диспетчер событий для решения сквозных задач. Это круто, но встроенный комментарий на самом деле является желаемой частью: P – Ocramius

+0

Я несколько понимаю, что говорит Маркус (через код), и согласен с @Ocramius в том, что это не так много кода, о котором я просил об этом было больше понимание того, как перейти от ресурсов Zend_Frameworks к тому, где теперь определить мои «ресурсы», чтобы они были доступны для широкого применения. Я начинаю писать более четкую картину с информацией в обоих ответах. Я подозреваю, что сейчас я проведу большую часть выходных, получая сильное понимание ModuleManager, EventManager и ServiceManager, и я думаю, что буду «преобразован» –

+0

. Я должен отметить, что самое сложное, что можно преодолеть, это логика событий в безжизненная среда, но она приходит ко мне :) –

 Смежные вопросы

  • Нет связанных вопросов^_^