Я хочу создать веб-сервис, к которому я отправлю форму, а в случае ошибок возвращает список, закодированный jason, который сообщает мне, какое поле является неправильным.
в настоящее время я получаю только список сообщений об ошибках, но не идентификатор html или имя полей с ошибками
вот мой текущий код
public function saveAction(Request $request) { $em = $this->getDoctrine()->getManager(); $form = $this->createForm(new TaskType(), new Task()); $form->handleRequest($request); $task = $form->getData(); if ($form->isValid()) { $em->persist($task); $em->flush(); $array = array( 'status' => 201, 'msg' => 'Task Created'); } else { $errors = $form->getErrors(true, true); $errorCollection = array(); foreach($errors as $error){ $errorCollection[] = $error->getMessage(); } $array = array( 'status' => 400, 'errorMsg' => 'Bad Request', 'errorReport' => $errorCollection); // data to return via JSON } $response = new Response( json_encode( $array ) ); $response->headers->set( 'Content-Type', 'application/json' ); return $response; }
это даст мне ответ вроде
{ "status":400, "errorMsg":"Bad Request", "errorReport":{ "Task cannot be blank", "Task date needs to be within the month" } }
но я действительно хочу что-то вроде
{ "status":400, "errorMsg":"Bad Request", "errorReport":{ "taskfield" : "Task cannot be blank", "taskdatefield" : "Task date needs to be within the month" } }
Как я могу это достичь?
Я использую это, он работает спокойно:
/** * List all errors of a given bound form. * * @param Form $form * * @return array */ protected function getFormErrors(Form $form) { $errors = array(); // Global foreach ($form->getErrors() as $error) { $errors[$form->getName()][] = $error->getMessage(); } // Fields foreach ($form as $child /** @var Form $child */) { if (!$child->isValid()) { foreach ($child->getErrors() as $error) { $errors[$child->getName()][] = $error->getMessage(); } } } return $errors; }
Я, наконец, нашел решение этой проблемы здесь , он нуждался только в небольшом исправлении, чтобы соответствовать последним изменениям symfony, и это работало как шарм:
Исправление состоит в замене строки 33
if (count($child->getIterator()) > 0) {
с
if (count($child->getIterator()) > 0 && ($child instanceof \Symfony\Component\Form\Form)) {
потому что с введением в symfony формы \ Button произойдет несоответствие типа в функции сериализации, которая всегда ожидает экземпляр Form \ Form.
Вы можете зарегистрировать его как услугу:
services: form_serializer: class: Wooshii\SiteBundle\FormErrorsSerializer
а затем использовать его, как предлагает автор:
$errors = $this->get('form_serializer')->serializeFormErrors($form, true, true);
Это делает трюк для меня
$errors = []; foreach ($form->getErrors(true, true) as $formError) { $errors[] = $formError->getMessage(); }
PHP имеет ассоциативные массивы, между тем у JS есть две разные структуры данных: объект и массивы.
JSON, который вы хотите получить, не является законным и должен быть:
{ "status":400, "errorMsg":"Bad Request", "errorReport": { "taskfield" : "Task cannot be blank", "taskdatefield" : "Task date needs to be within the month" } }
Таким образом, вы можете сделать что-то вроде этого, чтобы создать свою коллекцию:
$errorCollection = array(); foreach($errors as $error){ $errorCollection[$error->getId()] = $error->getMessage(); }
(предполагая, что метод getId () существует на объектах $ error)