在控制器中,我创建并使用我的模型
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
谢谢。
答案 0 :(得分: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');
//...
}
}
答案 1 :(得分:6)
决定。所以。要解决类模型的任务,必须实现ServiceLocatorAwareInterface接口。因此,注入ServiceManager将自动发生在您的模型中。请参阅上一个示例。
对于应用程序的表单和其他对象,此处提出了合适的方法http://michaelgallego.fr/blog/?p=205您可以创建基类表单extends 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的对象是自动在文件module.config.php的service_manager部分中你需要编写的
'invokables' => array(
'Album\Form\AlbumForm' => 'Album\Form\AlbumForm',
),
然后在您的控制器中,您可以创建一个表单
$form = $this->getServiceLocator()->get('Album\Form\AlbumForm');
表单将包含一个对象ServiceManager,它将允许其他依赖项。
感谢大家的帮助。
答案 2 :(得分:0)
getServicelocator()
会出错。所以它需要替代方式。
扩展AbstractTableGateway
或ServiceLocatorAwareInterface
有错误。
工厂实施将帮助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) 命名空间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',
),
),