3

フォームにバリデーターRecordExistsを追加しようとしていますが、「dbアダプターがありません」というエラーが表示されます。このバリデーターにdbアダプターを設定するにはどうすればよいですか?私はスケルトンアプリケーションの例を使用して、次のようなことをしようとしています(はい、$ dbAdapterが未定義であることを知っています:)この変数をdbアダプターリソースに変更する方法を探しています):

namespace Album\Model;

use Zend\InputFilter\Factory as InputFactory;     // <-- Add this import
use Zend\InputFilter\InputFilter;                 // <-- Add this import
use Zend\InputFilter\InputFilterAwareInterface;   // <-- Add this import
use Zend\InputFilter\InputFilterInterface;        // <-- Add this import

class Album implements InputFilterAwareInterface
{
    public $id;
    public $artist;
    public $title;
    protected $inputFilter;                       // <-- Add this variable

public function exchangeArray($data)
{
    $this->id     = (isset($data['id']))     ? $data['id']     : null;
    $this->artist = (isset($data['artist'])) ? $data['artist'] : null;
    $this->title  = (isset($data['title']))  ? $data['title']  : null;
}

// Add content to this method:
public function setInputFilter(InputFilterInterface $inputFilter)
{
    throw new \Exception("Not used");
}

public function getInputFilter()
{
    if (!$this->inputFilter) {
        $inputFilter = new InputFilter();
        $factory     = new InputFactory();

        $inputFilter->add($factory->createInput(array(
            'name'     => 'id',
            'required' => true,
            'filters'  => array(
                array('name' => 'Int'),
            ),
            'validators' => array(
                array(
                    'name'    => 'Db\RecordExists',
                    'options' => array(
                        'table' => 'album',
                        'field' => 'title',
                        'adapter' => $dbAdapter
                    ),
                ),
            ),
        )));

        $this->inputFilter = $inputFilter;
    }

    return $this->inputFilter;
}

}

4

3 に答える 3

7

'Album/Model/Album' ファクトリを作成し、dbAdapter を Album モデルに注入できます。

'service_manager' => array(
    'factories' => array(
        'Application/Model/Album' => function($sm){
            $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
            $album = new \Application\Model\Album();
            $album->setDbAdapter($dbAdapter);
            return $album;
        },
    ),
),

ここで、setDbAdapter および getDbAdapter メソッドを実装する必要があります。

namespace Application\Model;

class Album
{
    public $id;
    public $artist;
    public $title;

    private $_dbAdapter;

    public function exchangeArray($data)
    {
        $this->id     = (isset($data['id'])) ? $data['id'] : null;
        $this->artist = (isset($data['artist'])) ? $data['artist'] : null;
        $this->title  = (isset($data['title'])) ? $data['title'] : null;
    }

    public function setDbAdapter($dbAdapter) {
        $this->_dbAdapter = $dbAdapter;
    }

    public function getDbAdapter() {
        return $this->_dbAdapter;
   }
}

呼び出して、入力フィルターで dbAdapter を取得できます。$this->getDbAdapter();

ServiceLocator によってコントローラーで Album モデルを取得することを忘れないでください。そうしないと、モデルで dbAdapter を使用できません。

$album = $this->getServiceLocator()->get('Application/Model/Album');
于 2012-12-12T22:09:11.427 に答える
1

「ユーザー名が既に存在するかどうか」の検証を行うには、次のような Service Manager 構成設定の簡単な方法を実行します。

// config/autoload/global.php

 return array(
       'db' => array(
       'driver'   => 'Pdo',
       'dsn'      => 'mysql:dbname=zf2tutorial;host=localhost',
    ),

     'service_manager' => array(
       'factories' => array(
         'Zend\Db\Adapter\Adapter' => function ($serviceManager) {
            $adapterFactory = new Zend\Db\Adapter\AdapterServiceFactory();
               $adapter = $adapterFactory->createService($serviceManager);

               \Zend\Db\TableGateway\Feature\GlobalAdapterFeature::setStaticAdapter($adapter);

               return $adapter;
         }
      ),
   ),
);

これはコントローラーアクションで最初に静的dbアダプターを設定します(以前にアダプターを使用していない場合)

public function myAction () {
    $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
    ...
}

次の配列を getInputFilter() に追加します。

array(
  'table'   => 'users',
  'field'   => 'username',
  'adapter' => \Zend\Db\TableGateway\Feature\GlobalAdapterFeature::getStaticAdapter();
)

これがすべての人に役立つことを願っています。乾杯!!!

于 2013-07-25T09:20:26.233 に答える
0

@kierzniakはDbAdapterを注入するための良い方法を提供しました。私のソリューションはほとんど同じです。DbAdapterを注入するだけでなく、完全なServiceLocatorを注入します。ServiceLocatorを注入することで、システム構成、EventManagersも取得できます。解決策は次のとおりです。

ステップ1:アルバム\モデルを作成してServiceLocatorAwareInterfaceを実装し、サービスロケーターをアルバム\モデルに挿入できるようにします。

use Zend\ServiceManager\ServiceLocatorAwareInterface,
    Zend\ServiceManager\ServiceLocatorInterface;
class Album AbstractModel implements ServiceLocatorAwareInterface, InputFilterAwareInterface
{
    protected $serviceLocator;

    public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
    {
        $this->serviceLocator = $serviceLocator;
        return $this;
    }

    public function getServiceLocator()
    {
        return $this->serviceLocator;
    }
}

ステップ2、configまたはModule.phpでAlbum\Modelをサービスとして登録します

class Module
{
    public function getServiceConfig()
    {
        return array(
            'invokables' => array(
                'AlbumModel' => 'Album\Model\Album',
            ),
        );
    }
}

ステップ3、サービスでAlbumModelを呼び出しますが、クラスでは呼び出しません。

public function addAction()
{
    if ($request->isPost()) {
        $album = $this->getServiceLocator()->get('AlbumModel');
    }
}

ステップ4、AlbumModelでDbAdapterを使用できるようになりました。

'adapter' => $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');

上記の手順により、どこでもサービスを共有できます。これがお役に立てば幸いです。

于 2012-12-13T02:42:32.060 に答える