我想构建一个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的表单结构。但它似乎也不是正确的方式。
您是否有从使用数据库表动态加载数据并创建表单的函数的经验?我很高兴每一个想法或建议。
你可以尝试这样的事情
$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,因为你的用例实际上并不是它的意思 - 但我们也将它用于类似的情况。