Symfony2 недопустимая форма без ошибок
у меня проблема с формой CRUD, сгенерированной Symfony2. (С документами MongoDB, но я не думаю, что это связано)
в методе createAction () моего контроллера, когда я отлаживаю результат формы:
$form->isValid() // returns false
$form->getErrors() // returns en empty array(0) {}
Итак, я ничего не получаю с помощью form_errors(form)
на моем шаблоне веточки (который кажется нормальным из-за $form->getErrors()
пустая возврата)
и записанные значения не заменяются в форме...
у кого-нибудь есть идея?
11 ответов:
первое, что нужно понять, это проверка выполняется на модели, а не на форме. Форма может содержать ошибки,но только если она имеет поле, сопоставленное со свойством, которое не проверяет. Поэтому, если ваша форма не содержит недопустимое поле (возможно, a
NotNull
утверждение на свойство, которое не находится в форме), он не будет показывать ошибку.второе, что
$form->getErrors()
будут показаны только ошибки для этого уровня, каждый дочерний элемент формы может содержать свои собственные ошибки. Так что если вы хотите проверить ошибки, вы должны пройти через поля и вызвать getErrors на каждом поле. ЭлементgetErrors
метод в классе формы может быть обманчивым таким образом.
для отладки формы используйте
$form->getErrorsAsString()
вместо$form->getErrors()
.
$form->getErrorsAsString()
должен использоваться только для отладки form...it будет содержать ошибки каждого дочернего элемента, который не является случаем$form->getErrors()
.как Петр упоминает,
$form->getErrors()
не вернет сумму всех ошибок дочерних форм.чтобы понять, как форма может быть недействительной и иметь getErrors (), возвращающий пустой массив, вы можете посмотреть на isValid () метод класс формы symfony. Как вы можете видеть, есть 2 случая, когда форма недействительна, первый тест для общей формы и второй тест для каждого дочернего элемента.
public function isValid() { //... //CASE I : IF CHILD ELEMENTS HAVE ERRORS, $this->errors WILL CONTAIN //THE ERROR ON THE CHILD ELEMENT AND NOT ON THE GENERAL 'errors' FIELD //ITSELF if (count($this->errors) > 0) { return false; } //CASE II: AND THIS IS WHY WE ARE TESTING THE CHILD ELEMENTS AS WELL //TO CHECK WHETHER THERE ARE VALID OR NOT if (!$this->isDisabled()) { foreach ($this->children as $child) { if (!$child->isValid()) { return false; } } } return true; }
поэтому каждый дочерний элемент формы может содержать ошибку, но
$form->getErrors()
сам не вернет все ошибки. Рассматривая форму, которая имеет много дочерних элементов, вы обычно будете иметь $form - >getErrors () с ошибкой CSRF, если CSRF не является правильным.
обновление для Symfony 2.6
так что в зависимости от вас Symfony2 версия:
die($form->getErrorsAsString());
по состоянию на symfony2. 5 на
getErrorsAsString()
функция устарела (будет удалена в Symfony3) и вы должны использовать следующий метод:die((string) $form->getErrors()); // Main errors die((string) $form->getErrors(true)); // Main and child errors
по состоянию на в Symfony2.6, вы также можете использовать
dump
(dev environment) функция, если вы активировалиDebugBundle
:dump((string) $form->getErrors()); // Main errors dump((string) $form->getErrors(true)); // Main and child errors
у меня точно такая же проблема. Для меня форма была недействительной, но я не мог получить никаких ошибок с помощью
$form->getErrors()
или$form->getErrorsAsString()
. Позже я обнаружил, что забыл передать токен CSRF в форму, поэтому он не будет отправлен, и$form->handleRequest($request)
ничего не сделал (нет проверки). Как я увидел ответ @pit, я попытался использовать$form->submit($request); $form->getErrorsAsString();
Он вернул ошибку:
ошибка: маркер CSRF недопустим. Пожалуйста, попробуйте повторно отправить форму.
здесь есть какое-то объяснение в документации Symfony2:http://symfony.com/doc/current/book/forms.html#handling-form-submissions
для Symfony (>= 3.2 - 4), Вы можете использовать :
foreach($form->getErrors(true, false) as $er) { print_r($er->__toString()); }
чтобы увидеть ошибки, очевидно.
для меня форма не была отправлена, даже если у меня была кнопка отправки. Я добавил код для решения проблемы
$request = $this->get('request'); if($request->isMethod("POST")){ $form->submit($request); if($form->isValid()){ // now true } }
начиная с Symfony 3 и далее в соответствии с документацией вы должны использовать новую реализацию:
$errors = (string) $form->getErrors(true, false);
это вернет все ошибки в виде одной строки.
если вы отправляете данные через AJAX, вы, возможно, пропустили, чтобы включить имя формы на ключи данных и поэтому являются "жертвой"...
# line 100 of Symfony/Component/Form/Extension/HttpFoundation/HttpFoundationRequestHandler.php // Don't submit the form if it is not present in the request
это означает, что при попытке обработать запрос механизм обработки запроса не нашел имя вашей формы внутри GET/POST datas (что означает массив).
когда вы визуализируете форму обычным способом, каждое из ее полей содержит имя вашей формы в качестве префикса в свой атрибут name
my_form[child_field_name]
.при использовании ajax добавьте имя своей формы в качестве префикса в datas !
data : { "my_form" : { "field_one" : "field_one_value" ... } }
да правильно, что это говорят Peter Kruithof В SF 2.8 это моя функция,чтобы получить ошибки из полей
private function getErrorsForm(\Symfony\Component\Form\Form $form) { $response = array(); foreach ($form as $child) { foreach ($child->getErrors(true) as $error) { $response[$child->getName()][] = $error->getMessage(); } } return $response; }
я столкнулся с этой ошибкой и обнаружил, что забыл "обработать" запрос. Убедитесь, что у вас есть это вокруг...
public function editAction(Request $request) { $form = $this->createForm(new CustomType(),$dataObject); /** This next line is the one I'm talking about... */ $form->handleRequest($request); if ($request->getMethod() == "POST") { if ($form->isValid()) { ...
похоже, что у вас есть проблема проверки. Форма не является действительной при отправке. Я предполагаю, что вы используете аннотации для своей проверки. Убедитесь, что у вас есть это в верхней части объекта.
use Symfony\Component\Validator\Constraints as Assert;
а также это над каждым свойством
/** * @Assert\NotBlank() */
The
NotBlank()
может быть изменен на любое ограничение в соответствии с вашими потребностями.дополнительную информацию о проверке можно найти по адресу: http://symfony.com/doc/current/book/validation.html
дополнительную информацию об ограничениях Assert можно найти по адресу: http://symfony.com/doc/current/book/validation.html#constraints