php Zend Framework 2 中的服务定位器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12770966/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 04:11:51  来源:igfitidea点击:

Service locator in Zend Framework 2

phpzend-framework2

提问by Eremite

In controller I create and use my model so

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

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

How do I use this global Service Locator in another place of my project, for example, in the other model, and not only in any controller?

我如何在我的项目的另一个地方使用这个全局服务定位器,例如,在另一个模型中,而不仅仅是在任何控制器中?

Сonfiguration of the connection to the database is defined in the file: my_project/config/autoload/global.php

数据库连接的配置在文件中定义:my_project/config/autoload/global.php

Thank you.

谢谢你。

采纳答案by Eremite

Decided. So. For solving the task of classes of models must implement the interface ServiceLocatorAwareInterface. So injection ServiceManager will happen in your model automatically. See the previous example.

决定了。所以。为了解决模型类的任务,必须实现接口 ServiceLocatorAwareInterface。因此注入 ServiceManager 将自动发生在您的模型中。请参见前面的示例。

For forms and other objects of your application suitable method proposed here http://michaelgallego.fr/blog/?p=205You can to create a base class form extends BaseForm and implements ServiceManagerAwareInterface, from which you will inherit its forms in the application.

对于您的应用程序的表单和其他对象,这里提出了合适的方法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;
    }
}

To injection of the object of the ServiceManager was automatically in the file module.config.php in section service_manager you need to write

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

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

Then in your controller, you can create a form so

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

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

The form will contain an object ServiceManager, which will allow other dependencies.

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

Thanks all for your help.

感谢你的帮助。

回答by Elvan

Zend MVC will inject the ServiceLocator instance into a class implementing Zend\ServiceManager\ServiceLocatorAwareInterface. A simple implementation for a model table looks like the following:

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');
    //...
  }
}

回答by Marcus

getServicelocator()makes error. So it needs alternative way. And extends AbstractTableGatewayor ServiceLocatorAwareInterfacehave errors.

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

Factory implementation will help Controller to get objects.

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

*User sample code will be similar to album.

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

1) factory class ( RegisterControllerFactory.php) * copied function createUser in 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) controller( RegisterController ) namespace Users\Controller;

2)控制器(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

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',
   ),       
),