【问题标题】:How can I create a dynamic function that pulls data from mysql database and builds a form in Symfony 4?如何创建一个从 mysql 数据库中提取数据并在 Symfony 4 中构建表单的动态函数?
【发布时间】:2018-08-30 08:44:20
【问题描述】:

我想构建一个控制器,它将从数据库中加载数据并从中构建一个表单,但这取决于 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 构建一个表单,其中包含该表内的所有字段:

所以在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) "1@12.sw"
      ["isActive":"App\Entity\Members":private]=>
      bool(true)
    }

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

您对从数据库表中动态加载数据并创建表单的函数有任何经验吗?我为每一个想法或建议感到高兴。

【问题讨论】:

  • 你想做什么?只是问,因为可能有更简单的解决方案。
  • 如果您的所有实体都是 Doctrine 实体,您可以轻松使用 ClassMetaData,其中包含每个实体所需的所有信息,请参阅文档 here:例如使用$class = $em->getMetadataFactory()->getMetadataFor('Entities\User');
  • 为什么要将所有实体属性定义为表单输入?这种需求的目的是什么?这是一个奇怪的案例
  • @LBA 这也许就是我要找的……你能举个例子吗?
  • 那么我认为@LBA 的解决方案是可行的方法

标签: database forms symfony entity formbuilder


【解决方案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,因为您的用例并不是它的真正含义 - 但我们也将它用于类似的情况。

【讨论】:

  • 我刚刚测试了你的代码,但没有得到任何输出
  • 确保使用正确的 $entityName 并且 $em 设置为您的 EntityManager - 将无法查看您的代码。这是有效的。
  • 我添加了$em = $this->getDoctrine()->getManager();$EntityName = 'App\\Entity\\' . ucwords($slug);
  • 结果如何?当您硬编码像$entityName = 'App\\Entity\\Members' 这样的实体时会发生什么 - 请注意我使用的是 entityName 而不是 EntityName
  • 您甚至可以查看$classes = $cmf->getAllMetadata(); 以获取所有类的元数据,仅用于测试目的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多