2016-07-15 73 views
3

我有一個簡單的ZF2應用程序,它使用兩個表和一個服務,我試圖將它轉換爲在ZF3​​上運行。我無法弄清楚如何更新服務管理器代碼。這裏的控制器將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); 
    } 
} 

,因爲這是不再ZF3支持哪些代碼我應該使用getServiceLocator()調用,而不是一個例子嗎?在堆棧溢出的其他地方,有人回答了另一個問題,並建議使用createService函數,但這也已從ZF3中刪除。

+4

您是否考慮過使用工廠來構建控制器?在工廠(可以訪問服務管理器)中,你可以加載你的'AuthorTable'和'BookTitleTable'以及你的'SpydusServiceInterface'並用它們構建你的控制器。 – Thelonias

+2

在ZF3控制器類中不再可以識別ServiceLocator。這就是爲什麼你應該像@ Thelonias在他的評論中寫的那樣去做。創建一個工廠,在工廠內創建你的服務並將它們注入到你的控制器類的構造函數中。 – Wilt

回答

2

您將要創建一個工廠來構建控制器。這個新班級將實施FactoryInterface。在__invoke函數中,您將使用$ container實例來檢索控制器的所有依賴關係,並將它們作爲參數傳遞給構造函數,或將它們設置在構造函數實例中。然後從該函數返回你的控制器實例。

您的控制器需要更新字段以支持此操作。您還需要確保在您的配置中註冊您的工廠。

+0

感謝您的建議和有關$容器實例的詳細信息。需要注意的一點是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

得到了快速的問題..是否一個好主意,如果我們增加參數數字來使用db模型?例如,如果我有超過10個模型用於控制器。 – tradebel123

+0

@ tradebel123同樣的問題,解決方案是將db適配器添加到控制器參數? –