4

私の ZF2 スケルトン アプリケーションは、Zend ユーザー ガイドに従って正常に動作します。しかし今、アルバムのアーティストが文字列ではなく、db のアーティスト テーブルの外部キーになるように、アプリケーションを拡張しようとしてぐるぐる回っています。

アーティストを作成、編集、および表示するために必要なすべてのモデル、コントローラー、ビューを作成しましたが、これも正常に機能します。しかし、アルバムのリストにアーティストの名前が表示されるようにするには、どうすればこの 2 つを組み合わせることができるでしょうか?

ここで提案されているように、ハイドレーター戦略を使用しますか? もしそうなら、どうすれば実装できますか?Zend\Stdlib\Hydrator\Strategy のマニュアルには、ハイドレーター戦略を登録する場所が記載されていません。はい、短い実装コードがあります:

$foo = new Foo();
$foo->setFoo("bar");
$foo->setBar("foo");

$hydrator = new ClassMethods();
$hydrator->addStrategy("foo", new Rot13Strategy());

しかし、これはどこに行くのですか?私のAlbumControllerで?そして、ハイドレーターは「主にフォームに使用される」と誰もが言い続けるのはなぜですか?

それとも、結局私が探しているのはハイドレーターではありませんか? 解決策を探す中で、私がよく遭遇するもう 1 つの問題は、依存性注入です。繰り返しになりますが、この種のチュートリアルを見つけましたが、クラス A、B、および C を使用していて、それらすべてのコード フラグメントがどこにあるのかを教えてくれないと、概念を理解するのにあまり役立ちません。

私がやりたいことはかなり一般的だと思いますが、実際のチュートリアルが見つからないことに驚いています。何時間もの調査の結果、ブレークスルーに非常に近づいていると確信していますが、もう見ることができず、プッシュが必要です. ありがとう :-)

4

1 に答える 1

7

ハイドレーターは、フォームを使用する場合や、ストレージからエンティティを保存またはロードする場合など、オブジェクト/エンティティからデータを取得する必要があるときに使用されます。

オブジェクトに関連オブジェクトを追加するために Hydrator を使用することはありません (たとえば、アンチスト オブジェクトをアルバムに追加する場合など)。これはあなたのサービス/マッパーに任せます。

これが私がそれを行う方法の例です:

アルバム.php

<?php
class Album
{
     // .. properties / getters/setters etc ..

     public function setArtist(ArtistInterface $artist)
     {
         $this->artist = $artist;
     }

     public function getArtist()
     {
          return $this->artist;
     }
}

AlbumHydrator.php

これは異なる場合があります。ゲッター/セッターまたはプロパティを使用し、ベースハイドレーターを見て、どのルートを使用するかを決定します..

Hydrator は、Assembled オブジェクトを取得し、フォームを表示するか、永続化などに保存するために必要なデータを返します。

<?php
class AlbumHydrator // extends Zend\Stdlib\Hydrator\ClassMethods
{
    public function extract($object)
    {
         return array(
             'artist_id'   => $object->getArtist()->getId(),
             'albumn_name' => $object->getAlbumName()
         )
    }

    // .. etc
}

AlbumService.php

<?php
use Zend\ServiceManager\ServiceManagerAwareInterface;
use Zend\ServiceManager\ServiceManager; 

class AlbumService  implements ServiceManagerAwareInterface
{
    /**
     * Get an album, we'll also load any related objects here
     *
     * @param int
     */
    public function find($id)
    {
        $album = $this->_getAlbumMapper()->find($id);
        $artist = $this->_getArtistMapper()->findByAlbum($id);
        $album->setArtist($artist);

        return $album;
    }

     /**
     * Get the Mapper
     * 
     * @return  Application\Mappers\AlbumMapper
     */
    protected function _getAlbumMapper()
    {
        return $this->getServiceManager()
            ->get('AlbumMapper')
        ;
    }

    // ..
}

次のように Service Manager 構成でサービスをセットアップします。

'AlbumService' => function($sm) {
    $mapper = $sm->get('AlbumMapper');
    $service = new Application\Service\AlbumService();
    $service->setAlbumMapper($mapper);

    return $service;
},

次に、サービスを使用して、必要なオブジェクト グラフを作成します。エンティティごとに個別のマッパーがあり、サービスはマッパーを使用して必要なオブジェクトを生成できます。

通常、エンティティごとに Hydrator があり、マッパーはそれらを使用してオブジェクトを設定します。これは実装によって異なります。マッパーの代わりに TableGateway などを使用している可能性がありますが、それでも問題なく動作します。

コントローラー内でオブジェクトにアクセスする例

SomeController.php

public function albumAction()
{
    $id = (int) $this->params()->fromRoute('id', FALSE);
    if( ! $id) {
        // do something with errors etc ..
        return $this->redirect()->toRoute('default_route', array(
            'controller'    => 'index',
            'action'        => 'index'
        ));
    }
    $request = $this->getRequest();

    $album = $this->getServiceLocator()->get('AlbumService')->find($id);
    $artistName = $album->getArtist()->getName();

    return new ViewMdoel(
       'album'      => $ablum,
       'artistName' => $artistName
    );
}

コレクションを使用しているときにオブジェクト グラフにデータを入力するのは少しトリッキーですが、そのようなセットアップでは遅延読み込みと仮想プロキシを使用する傾向があります。これにより、必要なオブジェクトが必要になるまで、必要なオブジェクトの読み込みが基本的に延期されます。これらを確認してください。

http://phpmaster.com/intro-to-virtual-proxies-1/ http://phpmaster.com/intro-to-virtual-proxies-2/

于 2013-04-05T09:30:56.877 に答える