2012-10-07 29 views
12

En controlador puedo crear y utilizar mi modelo de maneraServicio de localización en Zend Framework 2

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

¿Cómo se utiliza este Servicio de localización global en otro lugar de mi proyecto, por ejemplo, en el otro modelo, y no solo en cualquier controlador?

Сonfiguration de la conexión a la base de datos se define en el archivo: mi_proyecto/config/carga automática/global.php

Gracias.

Respuesta

6

Decided. Asi que. Para resolver la tarea de las clases de modelos debe implementar la interfaz ServiceLocatorAwareInterface. Entonces, la inyección del ServiceManager ocurrirá automáticamente en su modelo. Ver el ejemplo anterior.

Para formularios y otros objetos de su aplicación, método adecuado propuesto aquí http://michaelgallego.fr/blog/?p=205 Puede crear un formulario de clase base que amplíe BaseForm e implemente ServiceManagerAwareInterface, del que heredará sus formularios en la aplicación.

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; 
    } 
} 

Para la inyección del objeto del ServiceManager fue automáticamente en el archivo module.config.php en la sección service_manager que necesita para escribir

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

Luego, en su controlador, puede crear una forma tan

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

El formulario contendrá un objeto ServiceManager, que permitirá otras dependencias.

Gracias por su ayuda.

15

Zend MVC inyectará la instancia de ServiceLocator en una clase que implementa Zend \ ServiceManager \ ServiceLocatorAwareInterface. Una implementación simple para una tabla de modelo es similar a la siguiente:

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

Bien, muchas gracias, realmente funciona! Y cómo estar con clases distintas de la clase se extiende AbstractTableGateway, por ejemplo, con las clases de los formularios (se extiende Zend \ Form), las clases de los elementos (se extiende Zend \ Form \ Element)? ¿Cómo usar el ServiceLocator allí?O úselo, ¿hay una mala idea? ... – Eremite

+0

Si la clase se crea a través del ServiceManager que implementa la interfaz conocida, el ServiceManager se inyecta después de que se crea la clase. Para Zend \ Form, esto puede plantear un problema ya que gran parte de la configuración de los elementos se realiza generalmente en el constructor (SM inyectado después de este punto). Hay una publicación en el blog que habla de esto: http://www.michaelgallego.fr/blog/?p=205 – DrBeza

+0

Entendí la esencia de tu método. No está claro cómo hacer que ServiceManager llame automáticamente al método setServiceManager cuando crea una instancia del formulario que amplía la clase de formulario que describe en su blog. Usted escribe la necesidad de usar la matriz 'invokables' para el ServiceManager, podría decir en detalle cómo hacerlo. Gracias. – Eremite

0

getServicelocator() comete un error. Por lo tanto, necesita una forma alternativa. Y extiende AbstractTableGateway o ServiceLocatorAwareInterface tienen errores.

La implementación en fábrica ayudará al controlador a obtener objetos.

* El código de muestra del usuario será similar al del álbum.

1) clase de fábrica (RegisterControllerFactory.php) * copiado createUser función de controlador de

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) controlador (RegisterController) de espacio de nombres de Usuarios \ 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', 
    ),  
), 
Cuestiones relacionadas