2013-06-04 2 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); 
      }, 
     ), 
    ); 
} 

Но я получаю Фатальная ошибка: Вызов функции члена ГЭТ() на не-объект
Что такое правильный способ получить ServiceLocator в классе модели?

ответ

7

Вы должны вводить зависимости валидатора в валидатор. Это можно сделать с помощью массива параметров, когда вы назначаете валидатор в поле формы. Я написал некоторые примеры кода, чтобы продемонстрировать, что я имею в виду:

Регистрация \ Validator \ 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, которая автоматически вводится на каждом валидаторе, который реализует интерфейс 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; 
    } 
}