【问题标题】:Zend Framework 2: How to get ServiceLocator in validation classZend Framework 2:如何在验证类中获取 ServiceLocator
【发布时间】:2013-06-04 19:33:51
【问题描述】:

我想在我的验证类中获取 ServiceLocator。我尝试从 Controller 实例中获取它,但它返回 null。

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

    }

}

模块.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 的正确方法是什么?

【问题讨论】:

    标签: zend-framework2 tablegateway


    【解决方案1】:

    您应该将验证器的依赖项注入验证器。当您将验证器分配给表单字段时,您可以通过选项数组执行此操作。 我写了一些示例代码来说明我的意思:

    注册\验证器\我的验证:

    <?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 的方法:

    注册\表单\我的表单:

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

      【讨论】:

        猜你喜欢
        • 2017-07-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-07
        • 2023-03-13
        • 1970-01-01
        相关资源
        最近更新 更多