2013-06-04 61 views
2

我想在我的驗證類中獲取ServiceLocator。我試着從Controller實例中獲取它,但它返回null。Zend Framework 2:如何在驗證類中獲取ServiceLocator

MyValidation.php 
namespace Register\Validator; 

use Zend\Validator\AbstractValidator; 
use Register\Controller\RegisterController; 

class MyValidation extends AbstractValidator { 

    /* 
    code... 
    */ 

    function isValid($value) 
    { 
     $controller = new RegisterController(); 
     $sm = $controller->getServiceLocator(); 
     $tableGateway = $sm->get('Register\Model\RegisterTable'); 
     $tableGateway->myValidationMethod($value); 

    } 

}

Module.php

public function getServiceConfig() 
{ 
    return array(
     'factories' => array(
      'Register\Model\RegisterTable' => function($sm) { 
       $tableGateway = $sm->get('RegisterTableGateway'); 
       $table = new RegisterTable($tableGateway); 
       return $table; 
      }, 
      'RegisterTableGateway' => function ($sm) { 
       $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter'); 
       $resultSetPrototype = new ResultSet(); 
       $resultSetPrototype->setArrayObjectPrototype(new RegisterUser()); 
       return new TableGateway('table-name', $dbAdapter, null, $resultSetPrototype); 
      }, 
     ), 
    ); 
} 

,但我得到致命錯誤:調用一個成員函數的get()非對象
什麼是正確的方法上在模型類中獲取ServiceLocator?

回答

7

您應該將驗證程序的依賴關係注入驗證程序。當您將驗證器分配給表單字段時,您可以通過選項數組來完成此操作。 我寫了一些示例代碼演示了我的意思:

註冊\驗證\ MyValidation:

<?php 
namespace Application\Validator; 

use Zend\Validator\AbstractValidator; 

class MyValidation extends AbstractValidator 
{ 
    protected $tableGateway; 

    public function __construct($options = null) 
    { 
     parent::__constructor($options); 
     if ($options && is_array($options) && array_key_exists('tableGateway', $options)) 
     { 
      $this->tableGateway = $options['tableGateway']; 
     }   
    } 

    public function isValid($value) 
    { 
     // ... 
    } 
} 

至於形式,你既可以實現ServiceLocatorAwareInterface,那麼它就會自動向服務定位器注入,或者使用工廠爲表單注入特定的依賴關係。

這裏是你將如何使用ServiceLocatorAwareInterface做到這一點:

註冊\表格\ MyForm的:

<?php 
namespace Register\Form; 

use Zend\Form\Form; 
use Zend\InputFilter\InputFilterProviderInterface; 
use Zend\ServiceManager\ServiceLocatorAwareInterface; 

class MyForm extends Form implements InputFilterProviderInterface, ServiceLocatorAwareInterface 
{ 
    protected $servicelocator; 

    public function __construct() 
    { 
     $this->add(array(
       'name' => 'myfield', 
       'attributes' => array(
         'type' => 'text', 
       ), 
       'options' => array(
         'label' => 'Field 1' 
       ), 
      ) 
     ); 
    } 

    public function setServiceLocator(ServiceLocatorInterface $serviceLocator) 
    { 
     $this->servicelocator = $serviceLocator; 
    } 

    public function getServiceLocator() 
    { 
     return $this->servicelocator; 
    } 

    public function getInputFilterSpecification() 
    { 
     return array(
      'myfield' => array(
       'required' => true, 
       'filters'  => array(), 
       'validators' => array(
         array(
          'name' => 'Application\Validator\MyValidator', 
          'options' => array(
           'tableGateway' => $this->getServiceLocator()->get('Application\Model\RegisterTable'), 
          ), 
         ), 
       ), 
      ), 
     ); 
    } 
} 

此外,它爲什麼要實例化您的驗證器類控制器的我不清楚。你真的不應該這樣做。

2

我選擇了不同的方法。

我將它從表單傳遞到驗證程序,而不是將它從表單傳遞到ValidatorManager,ValidatorManager自動注入到實現ServiceLocatorAware接口的每個驗證程序中。

<?php 

// Form 
public function getInputFilterSpecification(){ 
    $filter = new InputFilter(); 
    $factory = new InputFactory(); 

    // Inject SM into validator manager 
    $pm = $this->getServiceLocator()->get("ValidatorManager"); 

    $validatorChain = $factory->getDefaultValidatorChain(); 
    $validatorChain->setPluginManager($pm); 

    // Your validators here.. 
} 

// Validator 
class MyValidator extends AbstractValidator implements ServiceLocatorAwareInterface { 

    /** 
    * SM 
    * @var ServiceLocatorInterface 
    */ 
    private $serviceLocator; 

    /** 
    * Validate 
    */ 
    public function isValid($email){ 

     // Get the application config 
     $config = $this->getServiceLocator()->getServiceLocator()->get("config"); 

    } 

    /** 
    * ServiceLocatorAwarr method 
    * @param ServiceLocatorInterface $serviceLocator 
    * @return \Application\Module 
    */ 
    public function setServiceLocator(ServiceLocatorInterface $serviceLocator){ 
     $this->serviceLocator = $serviceLocator; 
     return $this; 
    } 

    /** 
    * ServiceLocatorAwarr method 
    * @return ServiceLocatorInterface 
    */ 
    public function getServiceLocator(){ 
     return $this->serviceLocator; 
    } 
}