如何创建一个从mysql数据库中提取数据并在Symfony 4中构建表单的动态函数?

问题描述 投票:0回答:1

我想构建一个Controller,它将从数据库加载数据并从中构建一个表单,但取决于slug。

public function form($slug, Request $request){
   $EntityName = 'App\\Entity\\' . ucwords($slug);
   $item= $this->getDoctrine()->getRepository($EntityName)->find($id);
   $form = $this->createFormBuilder($item)

所以这意味着,如果slug是例如products,那么我想从我的数据库表`产品构建一个表单,其中包含该表中的所有字段:

所以在products我有例如字段id, name, color。所以我需要的输出是

  ->add('id', TextType::class, array('attr' => array('class' => 'form-control')))
  ->add('name', TextType::class, array('attr' => array('class' => 'form-control')))
  ->add('color', TextType::class, array('attr' => array('class' => 'form-control')))

但是如果我的slug是例如members并且在我的members表中字段是id, username, email那么应该建立一个带有这个字段的表单:

 ->add('id', TextType::class, array('attr' => array('class' => 'form-control')))
  ->add('username', TextType::class, array('attr' => array('class' => 'form-control')))
  ->add('email', TextType::class, array('attr' => array('class' => 'form-control')))

我现在的问题是如何创建这些依赖于slug的字段。我想以某种方式从对象$item获取字段。这是$item的对象:

 object(App\Entity\Members)#4788 (6) {
      ["id":"App\Entity\Members":private]=>
      int(9)
      ["username":"App\Entity\Members":private]=>
      string(13) "123"
      ["plainPassword":"App\Entity\Members":private]=>
      NULL
      ["password":"App\Entity\Members":private]=>
      string(0) ""
      ["email":"App\Entity\Members":private]=>
      string(7) "[email protected]"
      ["isActive":"App\Entity\Members":private]=>
      bool(true)
    }

我试图使用get_object_vars,但这不适用于私有对象,所以我想这不是一个好的解决方案。我还尝试从对象创建一个数组($array = (array) $item;)来构建带有foreach的表单结构。但它似乎也不是正确的方式。

您是否有从使用数据库表动态加载数据并创建表单的函数的经验?我很高兴每一个想法或建议。

database forms symfony entity formbuilder
1个回答
1
投票

你可以尝试这样的事情

$cmf = $em->getMetadataFactory();
$class = $cmf->getMetadataFor($entityName);

foreach ($class->fieldMappings as $fieldMapping) {
  echo $fieldMapping['fieldName'] . "\n";
}

这将根据Doctrine的元数据模型为您的实体提供所有字段。

查看ClassMetadata API documentation了解更多信息,特别是您将获得哪些信息。

例如。你可以用类似的东西

  • isNullable(string $fieldName)确保一些'强制验证'
  • getIdentifierColumnNames()排除所有标识符列(注意:这将返回列名而不是实体字段,但您可以轻松识别这些
  • getTypeOfField得到一些暗示字段是字符串还是数字(再次允许更具体的表单属性)
  • 等等...只需检查文档并试一试

但是一般要小心使用ClassMetadata,因为你的用例实际上并不是它的意思 - 但我们也将它用于类似的情况。

© www.soinside.com 2019 - 2024. All rights reserved.