2

検証クラスで 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);

    }

}

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

しかし、私はFatal error: Call to member function get() on a non-object
を取得しますモデルクラスで ServiceLocator を取得する適切な方法は何ですか?

4

2 に答える 2

7

バリデーターの依存関係をバリデーターに注入する必要があります。バリデーターをフォームフィールドに割り当てるときに、オプション配列を介してそれを行うことができます。私が何を意味するかを示すために、いくつかのサンプルコードを書きました:

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

フォームに関しては、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'),
                            ),
                        ),
                ),
            ),
        );
    }
}

また、バリデータークラスでコントローラーをインスタンス化する理由も明確ではありません。あなたは本当にそれをすべきではありません。

于 2013-06-05T04:52:42.277 に答える
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;
    }
}
于 2014-10-18T13:54:21.923 に答える