Php Symfony2-使用表单类时如何设置和获取选项?

Php Symfony2-使用表单类时如何设置和获取选项?,php,symfony,Php,Symfony,我正在使用表单类在我的项目中构建各种表单 在实体类型文件中,对于buildForm函数,有一个次要参数“array$options”(这在正式的Symfony 2文档中显示,但从未提及过,永远!) 我已经在控制器中的createForm函数中输入了一个数组,但是现在我完全不知道如何检索存储的值 $form = $this->createForm(new ProductType(array(), array('id' => '2')), $product); 关于获取选项,我发现的唯

我正在使用表单类在我的项目中构建各种表单

在实体类型文件中,对于buildForm函数,有一个次要参数“array$options”(这在正式的Symfony 2文档中显示,但从未提及过,永远!)

我已经在控制器中的createForm函数中输入了一个数组,但是现在我完全不知道如何检索存储的值

$form = $this->createForm(new ProductType(array(), array('id' => '2')), $product);
关于获取选项,我发现的唯一一件事是使用getOption()函数,但这在Symfony 2中是不存在的(我找到的帖子是从2010年开始的)

我尝试使用:

$id = $options['id'];
但是,当我尝试在任何地方使用$id时,我会出现以下错误:

注意:未定义索引:id

有什么好处

如何从$options数组中检索值?我一开始就把它们设置正确了吗

编辑-更多代码:

形式类

<?php

namespace DEMO\DemoBundle\Form\Product;

use Doctrine\ORM\EntityRepository;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;

class ProductType extends AbstractType
{
    public function buildForm(FormBuilder $builder, array $options)
    {
        $builder
            ->add('name')
            ->add('slug')
            ->add('reference')
            ->add('description')
            ->add('active_from')
            ->add('active_till')
            ->add('is_active')
            ->add('category', 'entity', array(
                'class' => 'DEMO\DemoBundle\Entity\Product\ProductCategory',
                'query_builder' => function(EntityRepository $er) {
                    return $er->createQueryBuilder('u')
                        ->where('u.section = :id')
                        ->setParameter('id', ***ID VARIABLE NEEDS TO GO HERE***)
                        ->orderBy('u.root', 'ASC')
                        ->addOrderBy('u.lft', 'ASC');
                },
                'empty_value' => 'Choose an option',
                'property' => 'indentedName',
            ));
    }

    public function getDefaultOptions()
    {
        return array(
            'data_class' => 'DEMO\DemoBundle\Entity\Product\Product'
        );
    }

    public function getName()
    {
        return 'demo_demobundle_product_type';
    }
}

我认为您一开始没有正确设置它们。您应该将它们作为
createForm()

编辑:以下是表单类的外观:

<?php
namespace DEMO\DemoBundle\Form\Product;

use Doctrine\ORM\EntityRepository;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;

class ProductType extends AbstractType
{
    public function buildForm(FormBuilder $builder, array $options)
    {
        $builder
            ->add('name')
            ->add('slug')
            ->add('reference')
            ->add('description')
            ->add('active_from')
            ->add('active_till')
            ->add('is_active')
            ->add('category', 'entity', array(
                'class' => 'DEMO\DemoBundle\Entity\Product\ProductCategory',
                'query_builder' => function(EntityRepository $er) use($options) {
                    return $er->createQueryBuilder('u')
                        ->where('u.section = :id')
                        ->setParameter('id', $options['id'])
                        ->orderBy('u.root', 'ASC')
                        ->addOrderBy('u.lft', 'ASC');
                },
                'empty_value' => 'Choose an option',
                'property' => 'indentedName',
            ));
    }

    public function getDefaultOptions()
    {
        return array(
            'data_class' => 'DEMO\DemoBundle\Entity\Product\Product',
            'id'         => null
        );
    }

    public function getName()
    {
        return 'demo_demobundle_product_type';
    }
}

通过forms类
\u construct
方法传递选项,如下所示:

use Doctrine\ORM\EntityRepository;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;

class ProductType extends AbstractType
{

    private $options = array();
    public function buildForm(FormBuilder $builder, array $options)
    {
        $builder
            ->add('name')
            ->add('slug')
            ->add('reference')
            ->add('description')
            ->add('active_from')
            ->add('active_till')
            ->add('is_active')
            ->add('category', 'entity', array(
                'class' => 'DEMO\DemoBundle\Entity\Product\ProductCategory',
                'query_builder' => function(EntityRepository $er) {
                    return $er->createQueryBuilder('u')
                        ->where('u.section = :id')
                        ->setParameter('id', $this->options['id'])
                        ->orderBy('u.root', 'ASC')
                        ->addOrderBy('u.lft', 'ASC');
                },
                'empty_value' => 'Choose an option',
                'property' => 'indentedName',
            ));
    }

    public function getDefaultOptions()
    {
        return array(
            'data_class' => 'DEMO\DemoBundle\Entity\Product\Product'
        );
    }

    public function getName()
    {
        return 'demo_demobundle_product_type';
    }

    public function __construct(array $options)
    {
        $this->options = $options;
    }
}
然后你可以做:

new ProductType(array('id'=>1));

事实证明,Gregoires的答案非常接近,但在尝试实际将变量放入createQueryBuilder函数时,给了我和“Undefined variable”错误

我花了一段时间试图找出原因,并找到了问题所在。您必须向“查询生成器”选项中的函数添加一个额外参数,如下所示:

'query_builder' => function(EntityRepository $er) use ($options) {
                    return $er->createQueryBuilder('u')
                        ->where('u.section = :id')
                        ->setParameter('id', $options['id'])
                        ->orderBy('u.root', 'ASC')
                        ->addOrderBy('u.lft', 'ASC');
                },
神奇的设置是“使用($options)”。这允许您在查询生成器中成功地使用$options['id'.

根据这一点

“GregFire”是对的,事实上我已经试过了,效果非常好!!!。你说“我真的不想去“黑客”任何核心结构”,但你最终没有使用最好的方法。。事实上,在我看来,你最终做了你不想做的事

所以最后你应该这样做:

在formType上

public function buildForm(FormBuilder $builder, array $options)
{
    $builder
        ->add('name')
        ->add('slug')
        ->add('reference')
        ->add('description')
        ->add('active_from')
        ->add('active_till')
        ->add('is_active')
        ->add('category', 'entity', array(
            'class' => 'DEMO\DemoBundle\Entity\Product\ProductCategory',
            'query_builder' => function(EntityRepository $er) {
                return $er->createQueryBuilder('u')
                    ->where('u.section = :id')
                    ->setParameter('id', $options['id'])
                    ->orderBy('u.root', 'ASC')
                    ->addOrderBy('u.lft', 'ASC');
            },
            'empty_value' => 'Choose an option',
            'property' => 'indentedName',
        ));
}

public function getDefaultOptions()
{
    return array(
        'data_class' => 'DEMO\DemoBundle\Entity\Product\Product'
        'id' => null
    );
}
在控制器中

$form = $this->createForm(new ProductType(), $product, array('id' => $id ));

让我告诉你什么对我有用

在控制器中:

$form = $this->createForm(new UsersType(), $entity, array(
    'attr' => array('locationId' => $currentLocationId)));
在FormType中:

->add('location', 'entity', array(
        'class' => 'Ro\RoinventBundle\Entity\Locations',
         'query_builder' => function (\Doctrine\ORM\EntityRepository $er) use ($options)
        {
            if (isset($options['attr']['locationId']) && ($options['attr']['locationId'] != NULL))
            {
                return $er->createQueryBuilder('Locations')
                    ->where('Locations.id = :param')
                    ->setParameter('param', $options['attr']['locationId']);
            }
            //else do what you want
},
));

显然,它不再使用
getDefaultOptions()
,而是使用
setDefaultOptions()

否则它说

“我的自定义”选项不存在。已知选项有:“操作”、“属性”、“自动初始化”

因此,对于我来说,我必须更新setDefaultOptions,如下所示:

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array('my_custom_option' => false));
    // Others if needed, like in the documentation for : 'data_class' => 'VENDOR\Bundle\Entity\MyEntity', 'csrf_protection' => true
}
然后可以在
buildForm
方法中检索它

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $myCustomOption = $options['my_custom_option'];
}

我相信createForm()的第三个选项是设置如下选项:“attr”、“by_reference”、“cascade_validation”、“csrf_field_name”、“csrf_protection”、“csrf_provider”、“data”、“data_class”、“disabled”、“empty_data”、“error_冒泡”、“error_delay”、“error_mapping”、“error_type”、“field_error_error_type”、“help_block”、“help_inline”等等(基本上,我试过了,它说“选项“id”不存在。”)你可以修改表单类的getDefaultOptions()方法,告诉表单这个选项,并避免这个消息。Tbh,我真的不想去“黑客”任何核心结构。函数buildForm()显然有一个辅助参数来设置选项数组。我想知道它是如何被正确使用的。这不是对核心结构的攻击,这是一种方法,getDefaultOptions()是一个在表单类中的方法(如果您使用cli任务生成表单)。它在那里,以便您可以修改它。如果您不相信我,请相信文档:,它显示了对此方法的修改示例。该页面没有显示如何自定义getDefaultOptions()。它只显示了如何使用该方法的一些可用选项,例如CSRF保护和设置数据_类。请详细说明它在何处显示了如何定制允许我添加自己的参数的方法?我尝试了这种方法,结果出现了“Undefined variable”(未定义变量)错误。我准确地复制了它,所以我无法理解为什么会出现错误,就我而言,变量正在设置中…哈哈,是的,几天前就已经知道了,请查看我的答案:)谢谢你的帮助!很抱歉,它实际上是用greg0实现的,我复制的代码不正确。编辑它以清除它