Как я могу создать динамическую функцию, которая извлекает данные из базы данных mysql и строит форму в Symfony 4?

Я хочу создать контроллер, который будет загружать данные из базы данных и создавать на их основе форму, но в зависимости от слага.

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

Таким образом, это означает, что, если слагом является, например, 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')))

Но если мой пул, например, 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')))

Проблема для меня теперь в том, как создавать эти поля, зависящие от слага. Думал как-нибудь получить поля из объекта $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. Но это тоже не кажется правильным.

Есть ли у вас опыт работы с функциями, которые динамически загружают данные из таблиц базы данных и создают форму? Рад каждой идее или совету.

Что ты хочешь сделать? Просто спрашиваю, потому что может быть более простое решение.

Fabien Papet 30.08.2018 11:00

если все ваши объекты являются объектами Doctrine, вы можете легко использовать ClassMetaData, который содержит всю информацию, которая вам требуется для каждой сущности, см. документацию здесь: например. использовать $class = $em->getMetadataFactory()->getMetadataFor('Entities\User');

LBA 30.08.2018 11:59

Почему вы хотите определить все свойства вашей сущности как входные данные формы? Какова цель этой потребности? Это странный случай

Mcsky 30.08.2018 12:32

@LBA, возможно, это то, что я ищу ... Не могли бы вы привести пример?

peace_love 30.08.2018 14:52

@FabienPapet Например, у меня есть 100 разных таблиц. Для содержимого каждой таблицы я хочу иметь форму со всеми данными, чтобы я мог ее редактировать. Если я не найду для него динамической функции, мне придется писать каждую форму вручную. Ты знаешь, что я имею в виду?

peace_love 30.08.2018 14:57

@Mcsky Потому что я хочу сделать их доступными для редактирования

peace_love 30.08.2018 14:58

Тогда я думаю, что решение @LBA - это то, что нужно.

Fabien Papet 30.08.2018 15:31
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
0
7
86
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете попробовать что-то вроде этого

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

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

Это даст вам все поля для вашей сущности на основе модели метаданных Doctrine.

Посетите Документация по API ClassMetadata для получения дополнительной информации и особенно информации, которую вы там получите.

Например. вы могли бы использовать что-то вроде

  • isNullable(string $fieldName) для обеспечения некоторой "обязательной проверки"
  • getIdentifierColumnNames(), чтобы исключить все столбцы идентификаторов (примечание: это вернет имена столбцов, а не поля сущностей, но вы можете легко их идентифицировать
  • getTypeOfField, чтобы получить подсказку, является ли поле строкой или числом (опять же, чтобы разрешить более конкретные атрибуты формы)
  • и т.д ... просто проверьте документацию и попробуйте

НО, как правило, будьте осторожны при использовании ClassMetadata, поскольку ваш вариант использования на самом деле не то, для чего он предназначен, но мы также используем его для аналогичного случая.

Я только что проверил ваш код, но не получаю никаких результатов

peace_love 30.08.2018 15:07

убедитесь, что вы используете правильное имя $ entityName и что $ em установлен на ваш EntityManager - не сможет заглянуть в ваш код. это работает.

LBA 30.08.2018 15:09

Я добавил $em = $this->getDoctrine()->getManager(); и $EntityName = 'App\\Entity\\' . ucwords($slug);

peace_love 30.08.2018 15:10

и каков результат? что происходит, когда вы жестко кодируете одну сущность, например $entityName = 'App\\Entity\\Members' - также обратите внимание, что я использовал entityName вместо EntityName

LBA 30.08.2018 15:14

вы даже можете проверить $classes = $cmf->getAllMetadata();, чтобы получить метаданные для всех классов только для целей тестирования

LBA 30.08.2018 15:15

Хорошо, $classes = $cmf->getAllMetadata(); дает мне результат

peace_love 30.08.2018 15:23

тогда вы сможете определить, какую строку использовать для $ entityName в getMetadataFor ($ entityName)

LBA 30.08.2018 15:31

Вы про это: ["rootEntityName"]=> string(18) "App\Entity\Members"?

peace_love 30.08.2018 15:38

Это также дает мне вывод: $classes = $cmf->getMetadataFor($EntityName);, если я сделаю var_dump($classes)

peace_love 30.08.2018 15:41

Просто foreach не дает мне вывода

peace_love 30.08.2018 15:44
var_dump($classes) дает мне результат, но если я добавлю` foreach ($ classes-> fieldMappings как $ fieldMapping) {echo $ fieldMapping ['fieldName']. "\ п"; } `Тогда нет вывода
peace_love 30.08.2018 15:53
["fieldMappings"]=> array(5) { ["id"]=> array(9) { ["fieldName"]=> string(2) "id" ["type"]=> string(7) "integer" ["scale"]=> int(0) ["length"]=> NULL ["unique"]=> bool(false) ["nullable"]=> bool(false) ["precision"]=> int(0) ["id"]=> bool(true) ["columnName"]=> string(2) "id" }
peace_love 30.08.2018 15:55

Но в этом массиве тоже нет значения id

peace_love 30.08.2018 15:56

какие? посмотри на свою свалку! Это здесь. конечно, «эхо» ничего не «покажет». используйте $ fieldMapping ['fieldName'] для того, что вы хотите с ним делать. это не имеет ничего общего с вашим OP, это просто PHP.

LBA 30.08.2018 16:02

Теперь я запутался ... Я думал, что foreach выведет все поля таблицы базы данных?

peace_love 30.08.2018 16:05

Позвольте нам продолжить обсуждение в чате.

LBA 30.08.2018 16:06

Он выведет поля сущности (ваш собственный результат дампа это доказывает!), Но не столбец таблицы базы данных. А в Symfony «эхо» не «выводится» на экран. Довольно сложно объяснить эти основы в таком контексте.

LBA 30.08.2018 16:10

Другие вопросы по теме