Я хочу создать контроллер, который будет загружать данные из базы данных и создавать на их основе форму, но в зависимости от слага.
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. Но это тоже не кажется правильным.
Есть ли у вас опыт работы с функциями, которые динамически загружают данные из таблиц базы данных и создают форму? Рад каждой идее или совету.
если все ваши объекты являются объектами Doctrine, вы можете легко использовать ClassMetaData, который содержит всю информацию, которая вам требуется для каждой сущности, см. документацию здесь: например. использовать $class = $em->getMetadataFactory()->getMetadataFor('Entities\User');
Почему вы хотите определить все свойства вашей сущности как входные данные формы? Какова цель этой потребности? Это странный случай
@LBA, возможно, это то, что я ищу ... Не могли бы вы привести пример?
@FabienPapet Например, у меня есть 100 разных таблиц. Для содержимого каждой таблицы я хочу иметь форму со всеми данными, чтобы я мог ее редактировать. Если я не найду для него динамической функции, мне придется писать каждую форму вручную. Ты знаешь, что я имею в виду?
@Mcsky Потому что я хочу сделать их доступными для редактирования
Тогда я думаю, что решение @LBA - это то, что нужно.

Вы можете попробовать что-то вроде этого
$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, поскольку ваш вариант использования на самом деле не то, для чего он предназначен, но мы также используем его для аналогичного случая.
Я только что проверил ваш код, но не получаю никаких результатов
убедитесь, что вы используете правильное имя $ entityName и что $ em установлен на ваш EntityManager - не сможет заглянуть в ваш код. это работает.
Я добавил $em = $this->getDoctrine()->getManager(); и $EntityName = 'App\\Entity\\' . ucwords($slug);
и каков результат? что происходит, когда вы жестко кодируете одну сущность, например $entityName = 'App\\Entity\\Members' - также обратите внимание, что я использовал entityName вместо EntityName
вы даже можете проверить $classes = $cmf->getAllMetadata();, чтобы получить метаданные для всех классов только для целей тестирования
Хорошо, $classes = $cmf->getAllMetadata(); дает мне результат
тогда вы сможете определить, какую строку использовать для $ entityName в getMetadataFor ($ entityName)
Вы про это: ["rootEntityName"]=> string(18) "App\Entity\Members"?
Это также дает мне вывод: $classes = $cmf->getMetadataFor($EntityName);, если я сделаю var_dump($classes)
Просто foreach не дает мне вывода
var_dump($classes) дает мне результат, но если я добавлю` foreach ($ classes-> fieldMappings как $ fieldMapping) {echo $ fieldMapping ['fieldName']. "\ п"; } `Тогда нет вывода
["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" }Но в этом массиве тоже нет значения id
какие? посмотри на свою свалку! Это здесь. конечно, «эхо» ничего не «покажет». используйте $ fieldMapping ['fieldName'] для того, что вы хотите с ним делать. это не имеет ничего общего с вашим OP, это просто PHP.
Теперь я запутался ... Я думал, что foreach выведет все поля таблицы базы данных?
Позвольте нам продолжить обсуждение в чате.
Он выведет поля сущности (ваш собственный результат дампа это доказывает!), Но не столбец таблицы базы данных. А в Symfony «эхо» не «выводится» на экран. Довольно сложно объяснить эти основы в таком контексте.
Что ты хочешь сделать? Просто спрашиваю, потому что может быть более простое решение.