Zend framework2 如何将db适配器设置为Validator NoRecordExists并在控制器中使用它?

Zend framework2 如何将db适配器设置为Validator NoRecordExists并在控制器中使用它?,zend-framework2,Zend Framework2,我最近开始学习ZF2,希望有人能帮助我 我正在学习Rob Allen的Zend Framework 2教程(非常感谢@Rob Allen) 我还使用了@Allovice和@Maciej的解决方案(非常感谢这两位作者),我感到困惑,因为我没有在编辑操作中使用这个解决方案 我在'adapter'=>$this->getServiceLocator()->get('Zend\Db\adapter\adapter')中看到了致命错误:对非对象调用成员函数get() 1) 在Module.php中添加了

我最近开始学习ZF2,希望有人能帮助我

我正在学习Rob Allen的Zend Framework 2教程(非常感谢@Rob Allen)

我还使用了@Allovice和@Maciej的解决方案(非常感谢这两位作者),我感到困惑,因为我没有在编辑操作中使用这个解决方案

我在
'adapter'=>$this->getServiceLocator()->get('Zend\Db\adapter\adapter')中看到了
致命错误:对非对象调用成员函数get()

1) 在Module.php中添加了

3) 在addAction中的RegionController.php中,使用

$model=$this->getServiceLocator()->get('RegionModel')

而不是
$model=newregion()

这对addAction很好,但我不明白如何在editAction中使用它

我的

My RegionTable具有以下代码:

非常感谢所有回答我问题的人


向您致意,Ruslan。

您应该通过服务管理器实例化一个新实体,以使用数据库适配器,而不是使用从表中收集的实体的表单过滤器

您有几个选择:

  • 将输入过滤器移动到它自己的类中,并通过服务管理器进行实例化,以便注入数据库适配器
  • 将表网关工厂中的原型对象更改为通过service manager工厂实例化
  • 通过服务管理器实例化一个单独的实体,并从中获取输入过滤器
  • 我个人会选择选项1,因为它能更好地分离代码

    一些例子:

    选项1(我的选择):

    这涉及到将过滤器移动到它自己的文件和类,在注入数据库适配器的同时为它创建一个工厂。然后,我们将在控制器中通过服务管理器获取过滤器,并将过滤器应用于表单

    因此,首先将过滤器移动到ModName\src\ModName\Form\RegionFilter.php中的一个文件中,用模块名替换ModName

    并将代码更改为如下所示:

    
    
    然后,您将在Module.php中创建类似的工厂:

    公共函数getServiceConfig() { 返回数组( “工厂”=>数组( 'ModName\Form\RegionFilter'=>函数($sm){ $dbAdapter=$sm->get('Zend\Db\Adapter\Adapter'); 返回新的RegionFilter($dbAdapter); }, ), ); }
    最后,在控制器中,只需执行以下操作:

    if($request->isPost()){
    $filter=$this->getServiceLocator()->get('ModName\Form\RegionFilter');
    $form->setInputFilter($filter->getInputFilter());
    $form->setData($request->getPost());
    如果($form->isValid()){
    $this->getRegionTable()->save($form->getData());
    返回$this->redirect()->toRoute('zfcadmin/regions');
    }
    }
    
    选项2:

    这涉及到使用
    Region
    injected的实例构造表。然后您可以将原型设置为此

    因此,在您的表构造中:

    public function\u构造(适配器$Adapter,区域$Region)
    {
    $this->adapter=$adapter;
    $this->resultSetPrototype=newresultset();
    $this->resultSetPrototype->setArrayObject原型($region);
    $this->initialize();
    }
    
    然后你的工厂:

    公共函数getServiceConfig() { 返回数组( 'invokables'=>数组( 'RegionModel'=>'FcLibraries\Model\Region', ), “工厂”=>数组( 'FcLibraries\Model\RegionTable'=>函数($sm){ $region=$sm->get('RegionModel'); $dbAdapter=$sm->get('Zend\Db\Adapter\Adapter'); $table=新RegionTable($dbAdapter,$region); 返回$table; }, ), ); }
    您应该能够保持代码的其余部分不变。如控制器。现在我还没有测试过这个方法,所以我不是百分之百的认为它会工作,但我认为它应该。另外两种方法我以前也用过

    选项3(最简单):

    这涉及通过服务管理器获取一个单独的区域模型,并使用该模型将输入过滤器应用于表单

    公共函数editAction()
    {
    $id=(int)$this->params()->fromRoute('id',0);
    如果(!$id){
    返回$this->redirect()->toRoute('zfcadmin/region',数组(
    “操作”=>“添加”
    ));
    }
    $data=$this->getRegionTable()->get($id);
    $form=newregionform();
    $form->bind($data);
    $form->get('submitBtn')->setAttribute('value','Save');
    $request=$this->getRequest();
    如果($request->isPost()){
    $region=$this->getServiceLocator()->get('RegionModel');
    $form->setInputFilter($region->getInputFilter());
    $form->setData($request->getPost());
    如果($form->isValid()){
    $this->getRegionTable()->save($form->getData());
    返回$this->redirect()->toRoute('zfcadmin/regions');
    }
    }
    返回数组(
    'id'=>$id,
    'form'=>$form,
    );
    }
    

    我还没有测试代码,但你应该了解要点。任何问题都可以提问。

    不要使用从表中收集的实体的表单过滤器,而应该通过服务管理器实例化一个新实体以使用数据库适配器

    您有几个选择:

  • 将输入过滤器移动到它自己的类中,并通过服务管理器进行实例化,以便注入数据库适配器
  • 将表网关工厂中的原型对象更改为通过service manager工厂实例化
  • 通过服务管理器实例化一个单独的实体,并从中获取输入过滤器
  • 我个人会选择选项1,因为它将代码分开
    public function getServiceConfig()
    {
        return array(
            'invokables' => array(
                'RegionModel' => 'FcLibraries\Model\Region', //<-- added it
            ),
            'factories' => array(
                'FcLibraries\Model\RegionTable' => function ($sm) {
                    $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                    $table = new RegionTable($dbAdapter);
                    return $table;
                },
            ),
        );
    }
    
    /**
     * @var
     */
    protected $serviceLocator;
    /**
     * @param \Zend\ServiceManager\ServiceLocatorInterface $serviceLocator
     * @return Library
     */
    public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
    {
        $this->serviceLocator = $serviceLocator;
        return $this;
    }
    /**
     * @return \Zend\ServiceManager\ServiceLocatorInterface
     */
    public function getServiceLocator()
    {
        return $this->serviceLocator;
    }
    
            $inputFilter->add($factory->createInput(array(
                'name' => 'name',
                'required' => true,
                'filters' => $this->_filters,
                'validators' => array(
                    array(
                        'name' => 'StringLength',
                        'options' => array(
                            'encoding' => 'UTF-8',
                            'min' => 1,
                            'max' => 30,
                        ),
                    ),
                    array(
                        'name'    => 'Db\NoRecordExists',
                        'options' => array(
                            'table' => $this->table,
                            'field' => 'name',
                            //'exclude' => array(
                            //    'field' => 'id',
                            //    'value' => $this->id
                            //),
                            'adapter' => $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'),
                        ),
                    ),
                ),
            )));
    
    public function editAction()
    {
        $id = (int)$this->params()->fromRoute('id', 0);
        if (!$id) {
            return $this->redirect()->toRoute('zfcadmin/region', array(
                'action' => 'add'
            ));
        }
        $data = $this->getRegionTable()->get($id);
        $form = new RegionForm();
        $form->bind($data);
        $form->get('submitBtn')->setAttribute('value', 'Save');
        $request = $this->getRequest();
        if ($request->isPost()) {
            $form->setInputFilter($data->getInputFilter());
            $form->setData($request->getPost());
            if ($form->isValid()) {
                $this->getRegionTable()->save($form->getData());
                return $this->redirect()->toRoute('zfcadmin/regions');
            }
        }
        return array(
            'id' => $id,
            'form' => $form,
        );
    }
    
    /**
     * @param \Zend\Db\Adapter\Adapter $adapter
     */
    public function __construct(Adapter $adapter)
    {
        $this->adapter = $adapter;
        $this->resultSetPrototype = new ResultSet();
        $this->resultSetPrototype->setArrayObjectPrototype(new Region());
        $this->initialize();
    }
    public function get($id)
    {
        $id = (int)$id;
        $rowSet = $this->select(array('id' => $id));
        $row = $rowSet->current();
        if (!$row) {
            throw new \Exception("Could not find row $id");
        }
        return $row;
    }
    
    return array(
       'db' => array(
       'driver'   => 'Pdo',
       'dsn'      => 'mysql:dbname=zf2tutorial;host=localhost',
    ),
    
     'service_manager' => array(
       'factories' => array(
         'Zend\Db\Adapter\Adapter' => function ($serviceManager) {
            $adapterFactory = new Zend\Db\Adapter\AdapterServiceFactory();
               $adapter = $adapterFactory->createService($serviceManager);
    
               \Zend\Db\TableGateway\Feature\GlobalAdapterFeature::setStaticAdapter($adapter);
    
               return $adapter;
         }
      ),
    )
    
    array(
      'table'   => 'users',
      'field'   => 'username',
      'adapter' => \Zend\Db\TableGateway\Feature\GlobalAdapterFeature::getStaticAdapter();
    )