3

我有一个简单的 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 );
    }
}

我应该使用什么代码来代替 getServiceLocator() 调用,因为 ZF3 不再支持该调用?在 Stack Overflow 的其他地方,有人回答了另一个问题并建议使用 createService 函数,但这也已从 ZF3 中删除。

4

2 回答 2

3

有几种不同的方法,但您已经在使用最常见的一种:通过构造函数传递依赖项。您当前正在为您的$spydusService类执行此操作,因此将构造函数更改为也接受两个表类的参数,例如:

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);
            }
        )
    );
}
于 2016-07-16T17:31:00.367 回答
2

您将要创建一个工厂来构建控制器。这个新类将实现FactoryInterface. 在 __invoke 函数中,您将使用 $container 实例来检索控制器的所有依赖项,并将它们作为参数传递给构造函数或将它们设置在构造函数实例上。然后只需从该函数返回您的控制器实例。

您的控制器将需要更新字段以支持这一点。您还需要确保在您的配置中注册您的工厂。

于 2016-07-16T15:47:30.907 回答