如何在ZF2字段集中访问数据库适配器?

时间:2017-01-21 17:41:48

标签: php zend-framework zend-framework2 zend-form zend-db

我已经关注了一个示例,并希望将数据库适配器传递给字段集以创建下拉菜单。

以下代码是我如何调用字段集 如何在BrandFieldset类中访问数据库适配器?

$this->add(array(
    'type' => 'Application\Form\BrandFieldset',
    'name' => 'brand',
    'options' => array(
        'label' => 'Brand of the product',
    ),
));

2 个答案:

答案 0 :(得分:3)

实例化字段集是FormElementManager的责任。当您尝试访问表单,表单元素或字段集时,FormElementManager知道在哪里查找以及如何创建它。这种行为在框架的Default Services部分进行了总结。

由于访问表单元素的正确方法是从FormElementManager中检索它们,因此我会编写一个BrandFieldsetFactory来将该数据库适配器或其他依赖项注入到构造中的fieldset来实现此目的。

ZF3友好的fieldset工厂看起来像:

<?php
namespace Application\Form\Factory;

use Application\Form\BrandFieldset;
use Interop\Container\ContainerInterface;

class BrandFieldsetFactory
{
    /**
     * @return BrandFieldset
     */
    public function __invoke(ContainerInterface $fem, $name, array $options = null)
    {
        // FormElementManager is child of AbstractPluginManager 
        // which makes it a ContainerInterface instance
        $adapter = $fem->getServiceLocator()->get('Your\Db\Adapter');
        return new BrandFieldset($adapter);
    }
}

此时,BrandFieldset应该扩展Zend\Form\Fieldset\Fieldset,它的构造函数可能如下所示:

private $dbAdapter;

/**
 * {@inheritdoc}
 */
public function __construct(My/Db/Adapter $db, $options = [])
{
    $this->dbAdapter = $db;
    return parent::__construct('brand-fieldset', $options);
}

最后,在module.config.php文件中,我有一个配置来告诉FormElementManager这个工厂:

<?php

use Application\Form\BrandFieldset;
use Application\Form\Factory\BrandFieldsetFactory;

return [
    // other config

    // Configuration for form element manager
    'form_elements' => [
        'factories' => [
            BrandFieldset::class => BrandFieldsetFactory::class
        ],
    ],
];
  

提示:构造后,FormElementManager将自动调用BrandFieldset::init()方法。您可以将任何后置初始化逻辑放入此方法中。

答案 1 :(得分:1)

根据这些文档,我能够找到解决方案。

https://framework.zend.com/manual/2.1/en/modules/zend.form.advanced-use-of-forms.html

'form_elements' => array(
    'invokables' => array(
        'fieldset' => BrandFieldsetFactory::class
    )
)

我需要使用控制器中的服务定位器来调用表单,如下所示。

$sl = $this->getServiceLocator();
$form = $sl->get('FormElementManager')->get('Application\Form\CreateForm');

此外,我将__construct更改为init。