2013-02-14 3 views
6

저는 오랫동안 Zend Framework 1 개발자로서 Zend Framework 2를 배우기 시작했습니다. 새로운 용어로 머리를 감싸는 데 어려움을 겪고 있습니다.Zend Framework 2 - 응용 프로그램/모듈/서비스 관리자 - Oh My

위로 돌아 가기 ZF1로 돌아가서 애플리케이션에 전역 인 로거를 만들려면 application.ini 파일에 구성을 추가하고 부트 스트랩을 리소스로 초기화해야합니다. . 그럼 내 모듈 컨트롤러에서 부트 스트랩 리소스를 통해 로거에 액세스 할 수있었습니다.

ZF2를 입력하십시오. 모듈은 약간 다른 짐승이며, 자체적으로 포함되어 있지만, 응용 프로그램과 상호 작용하는 방법에 대해 약간 혼란 스럽습니다. 이것이 ServiceManager가 작동하는 곳인 것처럼 보입니다. 내 목표는, 내 모듈 (컨트롤러가 아니라 모듈 자체)을 사용하여 응용 프로그램이 로거를 정의했는지 여부를 확인하고, 있으면 로거를 모듈 전체에서 활용하는 것입니다. 응용 프로그램에서 로거를 정의하지 않으면 모듈에서 모듈 로깅을위한 로거를 정의하도록합니다.

이 질문은 또한 데이터베이스와 관련이 있습니다. 응용 프로그램에서 데이터베이스 연결의 논리를 정의하고 필요한 모듈의 논리를 모듈에 정의하도록하고 싶다고합시다. 얼마나 정확하게 구성하고 응용 프로그램에 이미 데이터베이스 리소스가 정의되어 있는지 어떻게/어디에서 확인할 수 있습니까?

참고 : Rob Allen의 빠른 시작 (내가 알기로는 정보가 부족하고 리소스가 부족하여 리소스가 부족하다는 단점을 지니고 있음)과 ZF2 (readthedocs) 및 봤 거든. 내가 알기로는 퍼즐의 특정 부분이 '어디로 가는가'에 관한 정보가 일반적으로 매우 모호하다는 것입니다.

답변

6

Zend Framework 1.x에서 아는 내용은 "응용 프로그램 리소스"입니다.

"응용 프로그램 자원"의 개념은 이른바 "services" (인트로 here)

타 변경 모듈 자체이다 젠드 의해 워크 (2)에 대체된다. ZF1에서 모듈은 주로 일부 요청을 처리하는 응용 프로그램의 하위 섹션이었습니다. ZF2에서는 더 이상 사실이 아닙니다. 모듈이 서비스 또는 컨트롤러를 정의하면 이제는 모든 응용 프로그램에서 액세스 할 수 있습니다. 일부 differences between ZF1 and ZF2 by Gary Hockin에 멋진 소개가 있습니다.

어쨌든, 모듈은 아니요입니다. 이들은 격리 된 환경에서 가능한 한 적은 종속성으로 개발되어야하지만 모든 응용 프로그램에 영향을 미치는 교차 관심 기능을 제공합니다.

특정 로거의 경우 모듈이 항상 로거를 정의하고 소비하는 것이 좋습니다. 어떤 조건 로거를 정의 할 수있는 것은 다음과 같은있다 : 당신은 모든 응용 프로그램에 걸쳐 '일부 로거 이름을'사용할 수있을 것

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')); 
      }); 
     } 
    } 
} 

.

다른 접근 방식은 로거 서비스를 정의하고 다른 모듈 또는 구성 나중에 그것을 무시하도록하는 것입니다 :

덜 유연하고 캐시 할 수 없지만, 더 높은이있는, getServiceConfig으로 달성
class MyModule 
{ 
    public function getConfig() 
    { 
     return array(
      'service_manager' => array(
       'factories' => array(
        'some-logger-name' => 'My\Logger\Factory\ClassName' 
       ), 
      ), 
     ); 
    } 
} 

동일 getConfig 이상 우선 순위는 (대체를 할 수 있습니다) 당신은 또한 폐쇄로 서비스 공장을 정의 할 수 있습니다 : 해당 없음 (그런 다음 심지어 어떤 로거를 결정하기 위해 사용할 수있는 설정 키를 정의 할 수

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

서비스를 나) 사용할 수 있습니다.

모듈 및 구성의 개념은 "last module wins"이기 때문에 모듈 또는 이전에로드 된 모듈에 'some-logger-name' 서비스를 정의 할 수 있습니다.

동일한 개념이 DB 연결에도 적용됩니다.

위에서 볼 수 있듯이 서비스로 이동하면 이미 어느 정도의 자유가 부여되었습니다.

"응용 프로그램"이 당신에게 뭔가를 정의하지는 않습니다 : 모듈은 서비스/구성/이벤트 등을 정의합니다. 실행중인 응용 프로그램은 이러한 모든 것들을 함께 구성합니다.

+0

:

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); }); } 

그런 다음, 예를 들어, 응용 프로그램에서 어디 에서 컨트롤러를 트리거 당신이 제공 한 링크를 훑어 보았습니다, 오늘부터 좀 깊이 깊이 살펴 보겠습니다). 위의 질문에서 부분적으로 언급 한 바와 같이 나는 투쟁했기 때문에 작업 흐름을 더 잘 이해하기 위해 ZF2 소스 코드를 읽었습니다. 귀하의 답변은 소스 코드를 읽는 것과 관련하여 매우 잘 설명되어 있습니다. 조각이 어떻게 어울리는 지 더 잘 파악하기 시작했습니다. 나는 당신이 ZF1에서 ZF2로 옮길 필요가있는 것과 똑같은 모양으로 당신이 제공 한 읽기 (링크)를 기대하고 있습니다! –

+0

ZF2의 새로운 릴리스와 함께 서비스 관리/이벤트 기반 스타일에 대한 프로세스 변경 량과 함께 현재까지 사용할 수있는 정보에 많은 양의 모호함이 있습니다 (적어도 내가 만났던 것에서부터). 전환을 잘 묘사하는 것처럼 제공 한 링크에 매우 감사드립니다. –

+0

@AaronMurray 마스터'ServiceManager'와'EventManager' 그리고 모든 것이 훨씬 더 쉽게 보일 것입니다. – Ocramius

3

특히 로깅의 경우에는 ServiceManager을 사용하는 것보다 캡슐화 된 방법이 더 좋습니다. ZF2는 본질적으로 이벤트 기반 프레임 워크이며이 이벤트 기반 아키텍처를 가능하게하는 기능을 우리의 이점으로 사용할 수 있습니다. 로깅은 완벽한 예입니다. 팩토리를 정의하는 대신 응용 프로그램의 어느 위치에서든 트리거 될 수있는 로거 이벤트 만 첨부하면됩니다.

Module.phplog 이벤트 리스너를 첨부 : 나는 크게 작성자 감사 (빠르게

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

이것은 실제로 모듈을 통해 사용할 수있는 "로거"가 아니라 기본적으로 교차 관리자 문제를 해결하기 위해 이벤트 관리자를 사용하는 방법에 대한 설명입니다. 멋지다. 그러나 인라인 코멘트는 실제로 원하는 부분이다 : P – Ocramius

+0

Markus가 (코드를 통해) 말하고있는 것을 다소 이해하고, @Ocramius에 동의한다. 내가 묻는 코드는 그다지 많지 않다. Zend_Frameworks의 '리소스'에서 현재 내 '리소스'를 정의하는 곳으로 이동하여 애플리케이션에 액세스 할 수 있도록하는 방법을 이해합니다. 나는 두 가지 대답 모두에 정보가있는 그림을 그리기 시작했다. 나는 ModuleManager, EventManager 및 ServiceManager에 대한 강건한 이해를 얻는 주말 대부분을 보내고 있으며 변환 된 것으로 생각합니다. –

+0

과거에 얻는 가장 어려운 일은 다음과 같은 이벤트의 논리입니다. 상태가없는 환경이지만 내게 다가오고 있습니다. –