Zend Framework 2: How to get ServiceLocator in validation class

扶醉桌前 提交于 2019-12-06 12:57:54

You should inject the dependencies of the validator into the validator. You could do that through the options array when you assign the validator to a form field. I wrote up some sample code to demonstrate what I mean:

Register\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)
    {
        // ...
    }
}

As for the form you can either implement the ServiceLocatorAwareInterface, so it gets automatically injected with the service locator, or else inject specific dependencies into the form using a factory for the form.

Here's how you would do it using the ServiceLocatorAwareInterface:

Register\Form\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'),
                            ),
                        ),
                ),
            ),
        );
    }
}

Also it's not clear to me why you are instantiating a Controller in your validator class. You really shouldn't do that.

I opted for a different approach.

Instead of passing the dependency from the form to the validator, I pass it from the form to the ValidatorManager, which is automatically injected on each validator that implements the ServiceLocatorAware Interface.

<?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;
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!