3

2 つのテーブルとサービスを使用する単純な ZF2 アプリケーションがあり、それを ZF3 で実行するように変換しようとしています。サービス マネージャー コードを更新する方法がわかりません。コントローラの 1 つの例を次に示します。

    <?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

2 に答える 2

3

いくつかの異なるアプローチがありますが、既に最も一般的な方法を使用しています。それは、コンストラクターを介して依存関係を渡すことです。現在、クラスに対してこれを行っているため$spydusService、コンストラクターを変更して、次のように 2 つのテーブル クラスの引数も受け入れるようにします。

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 に答える