В контроллере я создаю и использую мою модель так
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
Спасибо.
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'); //... } }
Приняли решение. Так. Для решения задачи классов моделей необходимо реализовать интерфейс 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 был автоматически в файле module.config.php в разделе service_manager вам нужно написать
'invokables' => array( 'Album\Form\AlbumForm' => 'Album\Form\AlbumForm', ),
Затем в вашем контроллере вы можете создать форму, чтобы
$form = $this->getServiceLocator()->get('Album\Form\AlbumForm');
Форма будет содержать объект ServiceManager, который позволит использовать другие зависимости.
Спасибо всем за вашу помощь.
getServicelocator()
делает ошибку. Поэтому он нуждается в альтернативном пути. Расширения AbstractTableGateway
или ServiceLocatorAwareInterface
имеют ошибки.
Реализация Factory поможет контроллеру получить объекты.
* Пример кода пользователя будет похож на альбом.
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) Пользователи \ 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', ), ),