如何获取 Symfony2 表单中实体字段的可能值?

How to get possible values of an entity field in Symfony2 forms?

我创建并维护了一个小包来序列化 Symfony2 Symfony\Component\Form\Form 对象。

当我在 formType 中有一个实体字段时,我想获取该字段的可能值。

例如:如果我有一个实体 spaceship 的表单,其中有一个实体字段作为目的地,它是一个 planet 对象。

使用 Symfony\Component\Form\Form::createView(),我会得到一个变量,该变量将生成一个 <select> 标签,该标签使用 form_widget().

进行多项选择

我想知道的是:如何在 PHP 服务中获取这组可能的值?我在表单和他的实体字段子项上尝试了 Symfony\Component\Form\Form::getData() 和其他类似函数,但它对我来说并没有 return 我数据库中的值集。

有谁知道获取这些值的方法吗?

(PS:抱歉我的英语不好。)

编辑:根据要求,我的包中用于序列化表单对象的部分:

<?php
namespace WTech\FormBundle\Transformer;
use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormConfigInterface;
use Symfony\Component\HttpFoundation\RequestStack;
/**
 * {@inheritdoc}
 */
class FormTransformer
{
    /** @var Request **/
    private $request;

    /**
     * {@inheritdoc}
     */
    public function __construct(RequestStack $request)
    {
        $this->request = $request->getMasterRequest();
    }

    /**
     * {@inheritdoc}
     */
    public function serializeForm(Form $form)
    {
        $fields = array_keys($form->all());
        $nbFields = count($fields);
        $config = $form->getConfig();

        $attributes = $config->getOptions();
        // Building the basic Form data
        $data = [
            'name' => $form->getName(),
            'action' => $this->buildAction($config->getAction()),
            'method' => $config->getMethod(),
            'attributes' => $attributes,
            'children' => [],
            'csrf' => $this->buildCsrfToken($config)
        ];

        // Look over the form fields
        for($i = 0; $i < $nbFields; ++$i)
        {
            $field = $form->get($fields[$i]);
            $children = $field->all();

            // If there is children, we ignore the current field (type repeated)
            // And we build the children fields
            if(count($children) > 0)
            {
                $this->addChildrenToFields($data, $field->getConfig()->getName(), $children);
                continue;
            }
            $this->buildField($data, $field);
        }
        return json_encode($data);
    }

    /**
     * {@inheritdoc}
     */
    public function addChildrenToFields(&$data, $parentName, $children)
    {
        reset($children);

        while($key = key($children))
        {
            $this->buildField($data, $children[$key], "[$parentName]");
            next($children);
        }
    }

    /**
     * {@inheritdoc}
     */
    public function buildField(&$data, $field, $parentName = '')
    {
        $name = $field->getName();
        $key = "{$parentName}[{$name}]";
        $config = $field->getConfig();
        $type = $config->getType()->getInnerType()->getName();

        $attributes = $config->getOptions();
        $data['children'][$key] = [
            'type' => $type,
            'label' => $this->buildLabel($name, $attributes),
            'label_class' => $this->buildLabelClass($attributes),
            'div_class' => $this->buildDivClass($attributes),
            'class' => $this->buildClass($attributes),
            'translation_domain' => $this->buildTranslationDomain($attributes)
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function buildAction($primaryAction)
    {
        return
            (!empty($primaryAction))
            ? $primaryAction
            : $this->request->getPathInfo()
        ;
    }

    /**
     * {@inheritdoc}
     */
    public function buildLabel($name, $attributes)
    {
        return
            (isset($attributes['label']))
            ? $attributes['label']
            : $name
        ;
    }

    /**
     * {@inheritdoc}
     */
    public function buildLabelClass($attributes)
    {
        return
            (isset($attributes['attr']['label_class']))
            ? $attributes['attr']['label_class']
            : ''
        ;
    }

    /**
     * {@inheritdoc}
     */
    public function buildDivClass($attributes)
    {
        return
            (isset($attributes['attr']['div_class']))
            ? $attributes['attr']['div_class']
            : ''
        ;
    }

    /**
     * {@inheritdoc}
     */
    public function buildClass($attributes)
    {
        return
            (isset($attributes['attr']['class']))
            ? $attributes['attr']['class']
            : ''
        ;
    }

    /**
     * {@inheritdoc}
     */
    public function buildTranslationDomain($attributes)
    {
        return
            (isset($attributes['translation_domain']))
            ? $attributes['translation_domain']
            : ''
        ;
    }

    /**
     * {@inheritdoc}
     */
    public function buildCsrfToken(FormConfigInterface $config)
    {
        if($config->hasOption('csrf_provider'))
        {
            return [
                'token' => $config->getOption('csrf_provider')->generateCsrfToken($config->getOption('intention')),
                'field_name' => "{$config->getName()}[{$config->getOption('csrf_field_name')}]"
            ];
        }
        return false;
    }
}

好的,所以解决方案非常简单。 entity 表单类型有一个 choice_list 选项返回一个 Symfony\Bridge\Doctrine\Form\ChoiceList\EntityChoiceList 对象。这将使您能够在从数据库加载后找到存储在表单类型中的值。