2016-07-15 3 views
3

У меня есть простое приложение ZF2, которое использует две таблицы и службу, и я пытаюсь преобразовать ее для запуска на ZF3. Я не могу решить, как обновить код сервис-менеджера. Вот пример одного из контроллеровПреобразование ZF2 Service Manager в 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); 
    } 
} 

Какой код следует использовать вместо (вызов getServiceLocator), так как это больше не поддерживается в ZF3? В другом месте на Stack Overflow кто-то ответил на другой вопрос и предложил использовать функцию createService, но это также было удалено из ZF3.

+4

Рассматривали ли вы использование фабрики для сборки контроллера? На заводе (который имеет доступ к диспетчеру сервиса) вы можете загрузить свои «AuthorTable» и «BookTitleTable», а также ваш «SpydusServiceInterface» и построить с ними контроллер. – Thelonias

+2

В классах контроллера ZF3 уже не известно ServiceLocator. поэтому вы должны делать то, что @Thelonias написал в своем комментарии; создать фабрику, создать свои службы внутри фабрики и ввести их в конструктор вашего класса контроллера. – Wilt

ответ

2

Вы собираетесь создать фабрику для сборки контроллера. Этот новый класс будет реализовывать FactoryInterface. В функции __invoke вы будете использовать экземпляр $ container для извлечения всех ваших зависимостей вашего контроллера и передать их как аргументы в конструкторе или установить их в экземпляре конструктора. Затем просто верните экземпляр вашего контроллера из этой функции.

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

+0

Благодарим вас за предложение и подробную информацию о экземпляре $ container. Один момент для наблюдения - это изменение местоположения 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 или отдельный заводский класс). Вы должны изменить это, чтобы перечислить дополнительные аргументы:

+1

получил быстрый вопрос .. это хорошая идея, если мы увеличим числа аргументов для использования моделей db ?, например, если у меня более 10 моделей для использования в контроллере.? – tradebel123

+0

@ tradebel123 тот же вопрос, решение заключается в добавлении db-адаптера в аргументы контроллера? –

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