12

在控制器中,我创建并使用我的模型,所以

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

谢谢你。

4

3 回答 3

15

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');
    //...
  }
}
于 2012-10-07T18:13:23.507 回答
6

决定了。所以。为了解决模型类的任务,必须实现接口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;
    }
}

要在 service_manager 部分的文件 module.config.php 中自动注入 ServiceManager 的对象,您需要编写

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

然后在您的控制器中,您可以创建一个表单

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

该表单将包含一个对象 ServiceManager,它将允许其他依赖项。

感谢你的帮助。

于 2012-10-09T05:52:18.417 回答
0

getServicelocator()犯错误。所以它需要另一种方式。并扩展AbstractTableGatewayServiceLocatorAwareInterface有错误。

工厂实现将帮助 Controller 获取对象。

*用户示例代码将类似于专辑。

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)控制器(RegisterController)命名空间用户\控制器;

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) 模块.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',
   ),       
),
于 2016-08-02T08:51:42.253 回答