dongsonghen9931 2014-04-09 09:22
浏览 45
已采纳

Zend FW2如何在工厂的表单类中使用适配器?

My goal is to select distinct records from database table, create array and send it as set of option to select type of form element and also i will need to use same data in form validation in haystack (data same as in options of form element) I thought i will be able to achieve this by creating factory which will return already existing adapter in factories

'adapter' => function($sm) { $dbAdapter= $sm->get('Zend\Db\Adapter\Adapter'); return $dbAdapter ; },

and after in forms and validator classes i planed to use service manager to get this adapter for sql query creation

/*protected $form;*/
protected $adapter;

public function getAdapter()
{
    if (!$this->adapter) {
        $this->adapter = $this->getServiceLocator()
                                  ->get('adapter');
    }

    return $this->adapter;
}

public function getDistinct(){ $sql = "SELECT DISTINCT (lw_folders.f_name), lw_folders.f_id FROM lw_folders INNER JOIN lw_links ON lw_folders.f_id = lw_links.f_id"; return $resultSet = $this->adapter->query($sql);}

But i get a lot of errors, one of them i saying that getServiceLocator() is not found in this form class.

Is my thoughts about usage right? Is there any other way to use custom query to get need records and use them in form class? Thanks for your time!

  • 写回答

2条回答 默认 最新

  • dongyakui8675 2014-04-09 12:12
    关注

    ZF2 makes it very easy to inject class dependencies using factories.

    This means that rather than injecting a ServiceLocator into your form you can use it within the factory to fetch the required service and inject that into the constructor instead.

    So what does your form class need in order to function?

    Firstly change the form __construct to include the array of options for the select list as the form will need these options when you display it.

    MyModule\Form\FooForm.php

    class FooForm extends Zend\Form\Form
    {  
        protected $barOptions = array();
    
        public function __construct(array $barOptions){
            $this->barOptions = $barOptions; 
        }    
    
        // Called automatically when we fetch the form from the service locator
        public function init(){
    
            $this->add(array(
                'name' => 'bar',
                'type' => 'Zend\Form\Element\Select',
                'options' => array(
                    'value_options' => $this->barOptions;
                )
            ));
        }
    }
    

    Secondly, create a factory to inject these options (where you can use the adapter to fetch them)

    MyModule\Form\Factory\FormFactory.php

    namespace MyModule\Form\Factory;
    
    use MyModule\Form\FooForm;
    use Zend\ServiceManager\ServiceLocatorInterface;
    use Zend\ServiceManager\FactoryInterface;
    
    class FooFormFactory implements FactoryInterface
    {
        public function createService(ServiceLocatorInterface $formElementManager)
        {
            $serviceManager = $formElementManager->getServiceLocator();
    
            $adapter = $serviceManager->get('Zend\Db\Adapter\Adapter');
            $results = $adapter->query('SELECT foo FROM bar');
    
            $options = array();
    
            // convert the $results into array $options that the value_options
            // will accept
            // 
            //  $options = array(1 => 'Option 1', 2 => 'Option 2'...)
    
            return new FooForm($options);
        }
    }
    

    Lastly add the service to the module.php file

    public function getServiceConfig()
    {
        'factories' => array(
            'MyModule\Form\FooForm' => 'MyModule\Form\Factory\FooFormFactory',
        ),
    }
    

    The beauty in this approach is that the Form does not care about how the data is loaded, all it needs to know is what the options are and the factory will deal with the loading of them.

    You can repeat this same process any other class that requires any other services from the service manager.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 kafka 分区副本增加会导致消息丢失或者不可用吗?
  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥15 stable diffusion
  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘
  • ¥15 perl MISA分析p3_in脚本出错
  • ¥15 k8s部署jupyterlab,jupyterlab保存不了文件
  • ¥15 ubuntu虚拟机打包apk错误