PagesController.php
$id = $request->request->get('id');
$target = $request->request->get('target');
$EntityName = 'App\\Entity\\' . ucwords($slug);
$em = $this->getDoctrine()->getManager();
$cmf = $em->getMetadataFactory();
$classes = $cmf->getMetadataFor($EntityName);
if ($request->request->get('target')){
$item = new $EntityName();
$item= $this->getDoctrine()->getRepository($EntityName)->find($id);
$formBuilder = $this->createFormBuilder($item);
foreach ($classes->fieldMappings as $fieldMapping) {
$formBuilder->add($fieldMapping['fieldName'], TextType::class, array('attr' => array('class' => 'form-control'), 'required' => true,));
}
$formBuilder->add('cancel', ButtonType::class, array('label' => 'Cancel','attr' => array('class' => 'cancel form-btn btn btn-default pull-right close_sidebar close_h')))
->add('save', SubmitType::class, array('label' => 'Save','attr' => array('id' => 'submit-my-beautiful-form','class' => 'form-btn btn btn-info pull-right','style' => 'margin-right:5px')));
$form = $formBuilder->getForm();
$form->handleRequest($request);
$response = new JsonResponse(
array(
'message' => 'Success',
'output' => $this->renderView('form.html.twig',
array(
'target' => $target,
'entity' => $item,
'form' => $form->createView(),
))), 200);
return $response;
} else {
$em = $this->getDoctrine()->getManager();
foreach ($classes->fieldMappings as $fieldMapping) {
$func = 'set'.$fieldMapping['fieldName'];
$args = $data['form['.$fieldMapping['fieldName'].']'];
$entity->$func($args);
}
$em->persist($entity);
$em->flush();
$response = new JsonResponse(array('id' => $data['form[id]']), 200);
return $response;
}
form.html.twig
<section class = "content-header" style = "margin-bottom:20px">
<h1 style = "float:left;margin-bottom:30px">Create Entry </h1>
</section>
<section class = "content" style = "clear:left">
<div class = "form-group">
{{ form_start(form) }}
{{ form_end(form) }}
</section>
Моя форма работает хорошо, когда я заполняю ее и нажимаю кнопку «Сохранить», она сохраняется в базе данных. Когда я оставляю все поля пустыми и нажимаю «Сохранить», ничего не происходит и появляется ошибка 500.
An exception occurred while executing 'INSERT INTO members (username, password, email, is_active) VALUES (?, ?, ?, ?)' with params ["", null, "", "1"]:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'password' cannot be null
На самом деле это нормально, потому что поля обязательны, но ошибки не отображаются в моей форме, даже если я добавил «required» = «true».
@YetiCGN Спасибо за ваше сообщение. Это не на лету, я очень долго работал, чтобы осознать это.
Я имею в виду, что ваша модель и форма создаются программно на лету во время выполнения. Они могут быть любыми, и вы не можете использовать функции языка или фреймворка для придания семантического значения и проверки таких вещей, как тип данных. Я знаю, что заманчиво иметь только один магический метод, делающий все, что бы вы его ни кормили, но это антипаттерн.
@YetiCGN У меня определена сущность, я только что обновил свой вопрос, добавив дополнительную информацию. Что такое класс типа формы? Вы имеете в виду "TextType :: class, PasswordType :: class" и т. д.?
Я имею в виду, что «форму можно создавать и использовать непосредственно в контроллере. Однако лучше создать форму в отдельном автономном классе PHP» -> symfony.com/doc/current/forms.html#creating-form-classes
@YetiCGN Вы имеете в виду это правильно: symfony.com/doc/current/reference/forms/types/form.html Мне просто нужно выяснить, как это сделать
Нет, это будет подформа. Вы можете встроить форму в другую с помощью этого. Я имею в виду «форму можно создать и использовать прямо в контроллере» -> вот что вы сейчас делаете. «Однако лучше создать форму в отдельном автономном классе PHP» -> это то, что вам следует делать. Таким образом, для каждой сущности будет соответствующий класс формы.

Итак, при использовании конструктора форм у вас есть доступ к:
$form->isSubmitted()
и
$form->isValid()
В результате вы можете сделать что-то вроде:
if ($form->isSubmitted() && $form->isValid()) {
// save to database
}
Мы хотим проверить, что форма отправлена, прежде чем проверять ее действительность, как если бы форма не была отправлена, нет необходимости проверять ее действительность, поскольку она будет ложной.
Это предотвратит вашу ошибку MySQL, потому что ваша форма технически недействительна, и вы пытаетесь очистить недопустимые данные. Очевидно, мы хотим сохранять наши данные только тогда, когда они действительны.
Конечно, если форма не работает, вы можете вернуть представление, и в шаблоне у вас будет доступ к
{{ form_errors() }}
Это, вероятно, покроет то, что вам нужно, но вы также можете передать своему шаблону что-то вроде
'formHasErrors' => $form->isSubmitted() && !$form->isValid(),
а затем в вашем шаблоне
{% if formHasErrors %}
Возможно, вы захотите сделать что-то еще, это позволит вам лучше контролировать свои поля, это отдельное поле, как показано ниже:
{{ form_start(form) }}
{{ form_label(form.name) }}
{{ form_errors(form.name, {'attr': {'class': 'form-input'}}) }}
{{ form_widget(form.name) }}
{{ form_end(form) }}
Очень важно выявлять ошибки и правильно их обрабатывать. Ваша реализация не проверила правильность формы, поэтому вы получали 500 ошибок.
Спасибо! Будет ли отображаться ошибка на месте поля? Я имею в виду, что если кто-то заполнил все поля и просто забыл пароль, возможно ли, что ошибка «Требуется пароль» находится сразу за этим полем?
Да, он должен отображать ошибку, связанную с полем, вызывающим ошибку.
Хорошо, я протестирую это именно так, как вы предлагаете, надеюсь, я все поставил на правильное место. Сообщу вам, сработало ли это.
Я не понимаю, почему ваше приложение написано так, как оно есть, поэтому мне сложно дать правильный совет. Кажется, вы возвращаете ответ, возможно, в ответе есть что-то вроде 'errors' => $ form-> getErrors (). Обычно с моего контроллера я возвращал представление. Сбросьте $ form-> getErrors () в вашем контроллере, isValid () и работайте с этим и своей логикой.
Вероятно, потому что я отправляю его через json: codehare.io/G8eJ0d Я думаю, что после того, как done(function(data){, вероятно, будет той частью, где мне нужно отлавливать ошибки, может ли это быть правильным?
Это очень похоже на магию «создать таблицу базы данных и формировать ее на лету», которая является анти-шаблоном. Я настоятельно рекомендую вам определить сущность и класс типа формы. Если у вас есть утверждение о сущности, оно будет автоматически проверено компонентом формы. В противном случае вам придется вызывать службу валидатора самостоятельно: symfony.com/doc/current/… Атрибут, который вы устанавливаете, является просто атрибутом HTML, никакая валидация не назначается просто путем установки
'required' => true. См. symfony.com/doc/current/reference/forms/types/…