2012-10-07 9 views
12

नियंत्रक मैं बना सकते हैं और अपने मॉडल उपयोग करती हैं इसलिएसेवा लोकेटर फ्रेमवर्क 2

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

मैं अपने प्रोजेक्ट का एक और जगह में इस वैश्विक सेवा लोकेटर का उपयोग कैसे करूँ, उदाहरण के लिए, अन्य मॉडल में, और नहीं में केवल किसी भी नियंत्रक में?

डेटाबेस के लिए कनेक्शन की Сonfiguration फ़ाइल में परिभाषित किया गया है: my_project/config/autoload/global.php

धन्यवाद।

उत्तर

6

फैसला। इसलिए। मॉडलों के वर्गों के कार्य को हल करने के लिए इंटरफ़ेस ServiceLocatorAwareInterface को कार्यान्वित करना होगा। तो इंजेक्शन ServiceManager स्वचालित रूप से आपके मॉडल में होगा। पिछले उदाहरण देखें।

आपके आवेदन के रूपों और अन्य वस्तुओं के लिए उपयुक्त विधि http://michaelgallego.fr/blog/?p=205 प्रस्तावित विधि के लिए आप बेसफॉर्म फॉर्म को बेसफॉर्म बढ़ा सकते हैं और 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 की वस्तु के इंजेक्शन के लिए खंड service_manager में फ़ाइल module.config.php में स्वचालित रूप से था आप अपने नियंत्रक में फिर

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

लिखने के लिए की जरूरत है, आप ऐसा एक रूप बना सकते हैं

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

इस फॉर्म में एक वस्तु ServiceManager होगा, जो अन्य निर्भरताओं की अनुमति देगा।

आपकी मदद के लिए धन्यवाद।

15

ज़ेंड एमवीसी ज़िन्द \ 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'); 
    //... 
    } 
} 
+0

ठीक है, धन्यवाद, यह वास्तव में काम करता है! और कक्षा के अलावा कक्षाओं के साथ कैसे रहना है सार सारटेबल गेटवे, उदाहरण के लिए, रूपों के वर्गों (ज़ेंड \ फॉर्म को बढ़ाता है), तत्वों के वर्ग (ज़ेंड \ फ़ॉर्म \ तत्व बढ़ाता है) के साथ? सर्विसलोकेटर का उपयोग कैसे करें?या इसका इस्तेमाल करें एक बुरा विचार है? .. – Eremite

+0

यदि क्लास सर्विसमैनेजर के माध्यम से बनाई गई है जो जागरूक इंटरफ़ेस लागू करती है तो क्लास बनने के बाद ServiceManager इंजेक्शन दिया जाता है। ज़ेंड \ फॉर्म के लिए यह एक मुद्दा उत्पन्न कर सकता है क्योंकि आमतौर पर सेट-अप तत्वों को कन्स्ट्रक्टर में किया जाता है (एसएम इस बिंदु के बाद इंजेक्शन दिया जाता है)। इसके बारे में एक ब्लॉग पोस्ट बात कर रही है - http://www.michaelgallego.fr/blog/?p=205 – DrBeza

+0

मैं आपकी विधि के बारे में समझ गया। यह स्पष्ट नहीं है कि जब आप फ़ॉर्म का उदाहरण बनाते हैं तो ServiceManager स्वचालित रूप से setServiceManager विधि को कॉल करने के लिए कैसे करें, जिसे आप अपने ब्लॉग में वर्णित फ़ॉर्म क्लास को विस्तारित करते हैं। आप ServiceManager के लिए सरणी 'invokables' का उपयोग करने की आवश्यकता लिखते हैं, क्या आप विस्तार से यह कह सकते हैं कि यह कैसे करें। धन्यवाद। – Eremite

0

getServicelocator() त्रुटि बनाता है। तो इसे वैकल्पिक तरीके की जरूरत है। और AbstractTableGateway या ServiceLocatorAwareInterface में त्रुटियां हैं।

फैक्टरी कार्यान्वयन नियंत्रक को वस्तुओं को प्राप्त करने में मदद करेगा।

* उपयोगकर्ता नमूना कोड एल्बम के समान होगा।

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 \ नियंत्रक;

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', 
    ),  
), 
संबंधित मुद्दे