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

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!

我的目标是从数据库表中选择不同的记录,创建数组并将其作为选项集发送,以选择类型 表单元素,我还需要在haystack中的表单验证中使用相同的数据(数据与表单元素的选项相同) 我想我将能够通过创建工厂来实现这一点,工厂将返回工厂中现有的适配器 p >

'adapter'=> function($ sm){ $ dbAdapter = $ sm-> get('Zend \ Db \ Adapter \ Adapter'); 返回$ dbAdapter; }, code> p> \ n

之后在表单和验证器类中我计划使用服务管理器来获取用于sql查询创建的适配器 p>

  / * protected $ form; * / 
protected $ 适配器; 
 
公共函数getAdapter()
 {
 if if(!$ this-> adapter){
 $ this-> adapter = $ this-> getServiceLocator()
  - > get(  'adapter'); 
} 
 
返回$ this-> adapter; 
} 
  code>  pre> 
 
 

public function getDistinct(){\ n $ 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 );}} code> p>

但我收到很多错误,其中一个我说在这个表单类 em>中找不到getServiceLocator()。 p>

我对使用的想法是正确的吗? 有没有其他方法可以使用自定义查询来获取需求记录并在表单类中使用它们? 谢谢你的时间! strong> p> div>

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.

i think you cannot use the getServiceLocator() inside a form class. But i think i can help with a work around if it can be of any use to you the way Im doing this. inside your form create a function

public function sentadapter($var){

print_r($var);die;
}

and inside a controller where you call your form

$form = $this->getServiceLocator()->get('SomeForm');
$sm = $this->getServiceLocator();
$this->adapter = $sm->get('Zend\Db\Adapter\Adapter');
$form->sentadapter($this->adapter);//with this line you pass the adapter to the form to that function

I don't know if this is helping you. I was able to print the adapter data inside the form class this way. But i don't know if this is the way you would like to use it. Cant think of anything else.