简体   繁体   中英

Convert ZF2 Service Manager to ZF3

I have a simple ZF2 application that uses two tables and a service and I'm trying to convert it to run on ZF3. I can't work out how to update the service manager code. Here's an example of one of the controllers

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

What code should I use instead of the getServiceLocator() call as this is no longer supported in ZF3? Elsewhere on Stack Overflow someone had replied to another question and suggested using a createService function but this has been dropped from ZF3 as well.

There are a couple of different approaches, but you're already using the most common one: passing the dependencies in through the constructor. You're currently doing this for your $spydusService class, so change the constructor to also accept arguments for the two table clases, something like:

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.]
}

then, somewhere you already have a factory for the SearchRestController (it might be a closure in your Module.php class, or a standalone factory class). You'll want to modify this to pass in the extra arguments:

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

You are going to want to create a factory to build controller. This new class will implement FactoryInterface . In the __invoke function, you'll use the $container instance to retrieve all of your dependencies of your controller and either pass them as arguments in the constructor or set them on the constructor instance. Then just return your controller instance from that function.

Your controller will need to be updated with fields to support this. You will also need to be sure to register your factory in your configuration.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM