2016-07-15 1 views
3

두 테이블과 서비스를 사용하는 ZF2 응용 프로그램이 간단합니다. ZF3에서 실행되도록 변환하려고합니다. 서비스 관리자 코드를 업데이트하는 방법을 알아낼 수 없습니다. 다음은 컨트롤러이 더 이상 ZF3에서 지원 될 때 어떤 코드 나는 getServiceLocator() 호출 대신 사용해야합니다 ZF2 서비스 관리자를 ZF3으로 변환

<?php 
namespace LibraryRest\Controller; 

use Zend\Mvc\Controller; 

use Library\Service\SpydusServiceInterface; 
use Library\Service\SpydusService; 
use Library\Model\BookTitle; 
use Library\Model\BookTitleTable; 
use Library\Model\Author; 
use Library\Model\AuthorTable; 

use Zend\Mvc\Controller\AbstractRestfulController; 
use Zend\View\Model\JsonModel; 

class SearchRestController extends AbstractRestfulController { 

    protected $bookTitleTable; 

    public function getBookTitleTable() { 
     if (! $this->bookTitleTable) { 
      $this->bookTitleTable = $this->getServiceLocator()->get ('BookTitleTable'); 
     } 
     return $this->bookTitleTable; 
    } 

    protected $authorTable; 

    public function getAuthorTable() { 
     if (! $this->authorTable) { 
      $sm = $this->getServiceLocator(); 
      $this->authorTable = $sm->get ('AuthorTable'); 
     } 
     return $this->authorTable; 
    } 

    protected $spydusService; 

    public function __construct(SpydusServiceInterface $spydusService) { 
     $this->spydusService = $spydusService; 
    } 

    public function getList($action, $first, $last) { 
     if ($action == 'search') { 
      return $this->searchAction ($first, $last); 
     } 
    } 

    public function searchAction() { 
     $message = array(); 
     $results = array(); 
     $first = urldecode ($this->params()->fromRoute ('first')); 
     $last = urldecode ($this->params()->fromRoute ('last')); 
     if ($this->getAuthorTable()->getAuthorId ($first, $last) === false) { 
      $results [0] = array ('count' => 0, 'message' => 'This author not found in database', 'first' => $first, 'last' => $last, 'title' => '', 'titleCode' => '', 'link' => '', 'authorId' => ''); 
     } else { 
      $authorId = $this->getAuthorTable()->getAuthorId ($first, $last)->author_id; 
      $books = $this->spydusService->searchBooks ($first, $last); 
      $count = count ($books); 
      foreach ($books as $foundTitle) { 
       if ($foundTitle->getMessage() == 'Nothing found') { 
        $results [0] = array ('count' => 0, 'message' => 'Nothing found by library search', 'first' => $first, 'last' => $last, 'title' => '', 'titleCode' => '', 'link' => '', 'authorId' => ''); 
        break; 
       } 
       $searchBooks = $this->getBookTitleTable()->getId ($foundTitle->getTitle(), $authorId); 
       if ($searchBooks->count() == 0) { 
        $addUrl = "http://newlib.rvw.dyndns.org/library/search/add/" . $authorId . '/' . $foundTitle->getTitle(); 
        $results [] = array ('count' => $count, 'message' => $foundTitle->getMessage(), 'title' => $foundTitle->getTitle(), 'titleCoded' => $foundTitle->getTitleCoded(), 'first' => $foundTitle->getAuthorFirst(), 'last' => $foundTitle->getAuthorLast(), 'link' => $foundTitle->getLink(), 'authorId' => $authorId, 'addUrl' => $addUrl); 
       } 
      } 
     } 
     if (count ($results) == 0) { 
      $results [0] = array ('count' => 0, 'message' => 'Nothing found by library search', 'first' => $first, 'last' => $last, 'title' => '', 'titleCode' => '', 'link' => '', 'authorId' => ''); 
     } 
     return new JsonModel ($results); 
    } 
} 

중 하나의 예? Stack Overflow에서 다른 사람이 다른 질문에 대답하고 createService 함수를 사용하여 제안했지만 ZF3에서도 삭제되었습니다.

+4

컨트롤러를 구축하기 위해 공장을 사용해 보셨습니까? (서비스 매니저에 접근 할 수있는) 팩토리에서는'AuthorTable'과'BookTitleTable'과'SpydusServiceInterface'를 적재하고 컨트롤러를 구성 할 수 있습니다. – Thelonias

+2

ZF3 컨트롤러 클래스에서는 더 이상 ServiceLocator를 인식하지 않습니다. 그래서 @Thelonias가 그의 코멘트에 쓴대로해야한다. 팩토리를 생성하고 팩토리에서 서비스를 생성 한 다음 컨트롤러 클래스의 생성자에 삽입하십시오. – Wilt

답변

2

컨트롤러를 만들 팩토리를 만들려고합니다. 이 새로운 클래스는 FactoryInterface을 구현합니다. __invoke 함수에서 $ container 인스턴스를 사용하여 컨트롤러의 모든 종속성을 검색하고 생성자에서 인수로 전달하거나 생성자 인스턴스에 설정합니다. 그런 다음 해당 기능에서 컨트롤러 인스턴스를 반환하십시오.

컨트롤러를 지원하기 위해 컨트롤러를 필드로 업데이트해야합니다. 또한 구성에 공장을 등록해야합니다.

+0

$ container 인스턴스에 대한 제안과 세부 사항에 감사드립니다. Zend \ ServiceManager \ Factory \ FactoryInterface 으로 Zend \ ServiceManager \ Factory \ FactoryInterface로 변경하는 것이 중요합니다. 약간의 어려움이 있었지만 마침내이 컨트롤러의 팩토리를 만들 수있었습니다. 이제 나머지 컨트롤러로! – user3017691

+0

@ user3017691 문제가 해결되면 답을 해결책으로 표시하십시오. – Thelonias

3

두 가지 접근 방식이 있지만 이미 가장 일반적인 방법을 사용하고 있습니다. 즉, 생성자를 통해 종속성을 전달합니다. 당신은 당신의 $spydusService 클래스에 대해 이렇게, 그래서 또한 두 개의 테이블 clases에 대한 인수를 받아들이는 생성자를 변경하고, 무엇인가 : 다음

class SearchRestController extends AbstractRestfulController 
{ 
    protected $bookTitleTable; 

    protected $authorTable; 

    protected $spydusService; 

    public function __construct(SpydusServiceInterface $spydusService, $bookTitleTable, $authorTable) 
    { 
     $this->spydusService = $spydusService; 
     $this->bookTitleTable = $bookTitleTable; 
     $this->authorTable = $authorTable; 
    } 

    [etc.] 
} 

, 어딘가에 당신은 이미 SearchRestController (가있을 수 있습니다에 대한 공장 Module.php 클래스의 클로저 또는 독립 실행 형 팩토리 클래스). 추가 인수를 전달하려면 다음을 수정하십시오.

public function getControllerConfig() 
{ 
    return array(
     'factories' => array(
      'SearchRestController' => function ($sm) { 
       $spydusService = $sm->get('SpydusService'); // this part you already have 
       $bookTitleTable = $sm->get('BookTitleTable'); 
       $authorTable = $sm->get('AuthorTable'); 

       return new SearchRestController($spydusService, $bookTitleTable, $authorTable); 
      } 
     ) 
    ); 
} 
+1

빠른 질문이 있습니다. 컨트롤러에서 사용할 모델이 10 개 이상이면 예제에서 DB 모델을 사용하도록 인수를 늘리면 좋은 생각입니까? – tradebel123

+0

@ tradebel123 동일한 질문, 해결책은 DB 어댑터를 컨트롤러 인수에 추가하는 것입니까? –

관련 문제