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 深度学习残差模块模型
  • ¥20 两个不同Subnet的点对点连接
  • ¥50 怎么判断同步时序逻辑电路和异步时序逻辑电路
  • ¥15 差动电流二次谐波的含量Matlab计算
  • ¥15 Can/caned 总线错误问题,错误显示控制器要发1,结果总线检测到0
  • ¥15 C#如何调用串口数据
  • ¥15 MATLAB与单片机串口通信
  • ¥15 L76k模块的GPS的使用
  • ¥15 请帮我看一看数电项目如何设计
  • ¥23 (标签-bug|关键词-密码错误加密)