web-dev-qa-db-ja.com

Zend Framework2のサービスロケーター

コントローラーでモデルを作成して使用するので

public function getAlbumTable()
{
    if (!$this->albumTable) {
        $sm = $this->getServiceLocator();
        $this->albumTable = $sm->get('Album\Model\AlbumTable');
    }
    return $this->albumTable;
}

このグローバルサービスロケーターをプロジェクトの別の場所、たとえば他のモデルで、コントローラーだけでなく使用するにはどうすればよいですか?

データベースへの接続の構成は、ファイルmy_project/config/autoload /global.phpで定義されています。

ありがとうございました。

12
Eremite

決定しました。そう。モデルのクラスのタスクを解決するには、インターフェイスServiceLocatorAwareInterfaceを実装する必要があります。そのため、インジェクションServiceManagerはモデルで自動的に発生します。前の例を参照してください。

ここで提案されているアプリケーションの適切なメソッドのフォームおよびその他のオブジェクトの場合 http://michaelgallego.fr/blog/?p=205 基本クラスフォームを作成してBaseFormを拡張し、ServiceManagerAwareInterfaceを実装できます。アプリケーションでそのフォームを継承します。

namespace Common\Form;

use Zend\Form\Form as BaseForm;
use Zend\ServiceManager\ServiceManager;
use Zend\ServiceManager\ServiceManagerAwareInterface;

class Form extends BaseForm implements ServiceManagerAwareInterface
{
    /**
     * @var ServiceManager
     */
    protected $serviceManager;

    /**
     * Init the form
     */
    public function init()
    {
    }

    /**
     * @param ServiceManager $serviceManager
     * @return Form
     */
    public function setServiceManager(ServiceManager $serviceManager)
    {
        $this->serviceManager = $serviceManager;

        // Call the init function of the form once the service manager is set
        $this->init();

        return $this;
    }
}

ServiceManagerのオブジェクトを挿入するには、service_managerセクションのmodule.config.phpファイルに自動的に記述します。

'invokables' => array(
    'Album\Form\AlbumForm' => 'Album\Form\AlbumForm',
),

次に、コントローラーでフォームを作成できます。

$form = $this->getServiceLocator()->get('Album\Form\AlbumForm');

フォームには、他の依存関係を許可するオブジェクトServiceManagerが含まれます。

助けてくれてありがとう。

6
Eremite

Zend MVCは、ServiceLocatorインスタンスをZend\ServiceManager\ServiceLocatorAwareInterfaceを実装するクラスに挿入します。モデルテーブルの簡単な実装は次のようになります。

<?php
use Zend\Db\TableGateway\AbstractTableGateway;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

class UserTable extends AbstractTableGateway implements ServiceLocatorAwareInterface {
  protected $serviceLocator;

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

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

  // now instance of Service Locator is ready to use
  public function someMethod() {
    $table = $this->serviceLocator->get('Album\Model\AlbumTable');
    //...
  }
}
15
Elvan

getServicelocator()はエラーになります。したがって、別の方法が必要です。また、extends AbstractTableGatewayまたはServiceLocatorAwareInterfaceにエラーがあります。

工場での実装は、コントローラーがオブジェクトを取得するのに役立ちます。

*ユーザーサンプルコードはアルバムと同様になります。

1)ファクトリクラス(RegisterControllerFactory.php)*コントローラにコピーされた関数createUser

namespace Users\Controller\Factory;

use Users\Controller\RegisterController;

use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\ServiceManager\Exception\ServiceNotCreatedException;


class RegisterControllerFactory   
{

    public function __invoke($serviceLocator)
    {  
    $sm = $serviceLocator;
    $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');

    $resultSetPrototype = new \Zend\Db\ResultSet\ResultSet();
    $resultSetPrototype->setArrayObjectPrototype(new \Users\Model\User);
    $tableGateway       = new \Zend\Db\TableGateway\TableGateway('user' /* table name  */, $dbAdapter, null, $resultSetPrototype);

    $user = new \Users\Model\User();  
    $userTable = new \Users\Model\UserTable($tableGateway);

    $controller = new RegisterController($userTable, $serviceLocator );
    return $controller;

   }
} 

2)controller(RegisterController)名前空間Users\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;

use Users\Form\RegisterForm;
use Users\Form\RegisterFilter;

use Users\Model\User;
use Users\Model\UserTable;

use Zend\ServiceManager\ServiceLocatorInterface;

class RegisterController extends AbstractActionController
{
    protected $userTable;
    protected $serviceManager;

    public function __construct(UserTable $userTable, ServiceLocatorInterface     $serviceManager)
{
    $this->userTable = $userTable;
    $this->serviceManager = $serviceManager;
}

public function indexAction()
{
    $form = new RegisterForm();
    $viewModel  = new ViewModel(array('form' => $form)); 
    return $viewModel; 
}

public function processAction()
{
    if (!$this->request->isPost()) {
        return $this->redirect()->toRoute(NULL , array( 
                    'controller' => 'register', 
                    'action' =>  'index' 
                ));
    }

    $post = $this->request->getPost();

    $form = new RegisterForm();
    $inputFilter = new RegisterFilter();
    $form->setInputFilter($inputFilter);

    $form->setData($post);
    if (!$form->isValid()) {
        $model = new ViewModel(array(
            'error' => true,
            'form'  => $form,
        ));
        $model->setTemplate('users/register/index');
        return $model;
    }

    // Create user
    $this->createUser($form->getData());

    return $this->redirect()->toRoute(NULL , array( 
                    'controller' => 'register', 
                    'action' =>  'confirm' 
                ));
}

public function confirmAction()
{
    $viewModel  = new ViewModel(); 
    return $viewModel; 
}

protected function createUser(array $data)
{  /*able to delete or modify */
    $sm = $this->serviceManager;
    $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');

    $resultSetPrototype = new \Zend\Db\ResultSet\ResultSet();
    $resultSetPrototype->setArrayObjectPrototype(new \Users\Model\User);
    $tableGateway       = new \Zend\Db\TableGateway\TableGateway('user' /* table name  */, $dbAdapter, null, $resultSetPrototype);

    $user = new User();
    $user->exchangeArray($data);

    $userTable = new UserTable($tableGateway);
    $userTable->saveUser($user);

    return true;
    }
}

3)module.config.php

return array(   
    'controllers' => array(
    'invokables' => array(
        'Users\Controller\Index' => 'Users\Controller\IndexController', 
        'Users\Controller\login' => 'Users\Controller\LoginController', 
        //delete 'Users\Controller\Register'
    ),
    'factories' => array(
            'Users\Controller\Register' =>     'Users\Controller\Factory\RegisterControllerFactory',
   ),       
),
0
Marcus