Symfony2 неверная форма без ошибок

49

У меня проблема с созданной Symfony2 формой CRUD. (С документами MongoDB, но я не думаю, что это связано)

В моем методе createAction() моего контроллера, когда я отлаживаю результат формы:

$form->isValid() // returns false

$form->getErrors() // returns en empty array(0) {}

Итак, я ничего не получаю, используя form_errors(form) в моем шаблоне twig (что кажется нормальным из-за $form->getErrors() пустого возврата)

И записанные значения не заменяются в форме...

Есть ли у кого-нибудь идеи?

  • 0
    Вы можете отредактировать свой вопрос, включив в него свой validation.xml или аннотации для проверки.
Теги:
validation
forms

11 ответов

51
Лучший ответ

Первое, что нужно понять, - это проверка на модель, а не на форму. Форма может содержать ошибки, но только если у нее есть поле, сопоставленное с свойством, которое не проверяется. Поэтому, если ваша форма не содержит недопустимое поле (возможно, утверждение NotNull для свойства, которое не находится в форме), оно не покажет ошибку.

Во-вторых, $form->getErrors() будет показывать только ошибки для этого уровня, каждый из которых может содержать свои собственные ошибки. Поэтому, если вы хотите проверить ошибки, вы должны пройти через поля и вызвать getErrors в каждом поле. Метод getErrors в классе Form может обманывать этот путь.

  • 2
    Я не знал этого, спасибо, я думаю, что нашел ответ. Я попробую !
  • 2
    Если вы это сделали, отметьте это как принятый ответ, чтобы другие люди с этим вопросом тоже могли извлечь из него пользу.
Показать ещё 2 комментария
58

Чтобы отладить форму, используйте $form->getErrorsAsString() вместо $form->getErrors().

$form->getErrorsAsString() должен использоваться только для отладки формы... он будет содержать ошибки каждого дочернего элемента, что не относится к $form->getErrors().

Как упоминает Питер, $form->getErrors() не вернет сумму всех ошибок дочерних форм.

Чтобы понять, как форма может быть недействительной и иметь getErrors(), возвращающую пустой массив, вы можете взглянуть на isValid() метод symfony класс формы. Как вы можете видеть, есть два случая, когда форма недействительна, первый тест для общей формы и второй случайный тест для каждого дочернего элемента.

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 неверен.

  • 1
    Большое спасибо за этот ответ. Без этого мне пришлось бы тратить много времени на отладку неверного поля.
  • 4
    $ form-> getErrorsAsString () устарела в Symfony 2.5+
Показать ещё 3 комментария
45

Обновление для Symfony 2.6

Итак, в зависимости от вас версия Symfony2:

die($form->getErrorsAsString());

По , < Функция t21 > устарела (будет удалена в Symfony3), и вы должны использовать следующий метод:

die((string) $form->getErrors());     // Main errors
die((string) $form->getErrors(true)); // Main and child errors

Как , вы можете также используйте функцию dump (dev), если вы активировали DebugBundle:

dump((string) $form->getErrors());     // Main errors
dump((string) $form->getErrors(true)); // Main and child errors
  • 2
    Спасибо, не заметил этого!
  • 1
    Этот помог мне решить мою проблему, спасибо! (Использование Symfony 2.8)
Показать ещё 1 комментарий
16

У меня только такая же проблема. Для меня форма недействительна, но я не мог получить никаких ошибок, используя $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

  • 0
    Спасибо, это решение сработало для меня
  • 0
    спасибо это был спасатель
3

Для меня форма не была отправлена, даже если у меня была кнопка отправки. Я добавил код для решения проблемы

$request = $this->get('request');
if($request->isMethod("POST")){
      $form->submit($request);
        if($form->isValid()){
        // now true
        }
}
  • 0
    Выглядит очень странно, разве у вас нет нескольких форм на одной странице?
  • 5
    Возможно, вам не хватало $ form-> handleRequest ($ this-> getRequest ()); инструкция. Он должен быть вызван перед проверкой isValid () .
2

Начиная с Symfony 3 в соответствии с документацией вы должны использовать новую реализацию:

$errors = (string) $form->getErrors(true, false);

Это возвращает все ошибки как одну строку.

2

Если вы отправляете данные через 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 (что означает как массив).

При визуализации формы обычным способом каждое из своих полей содержит ваше имя формы в качестве префикса в свой атрибут name my_form[child_field_name].

При использовании ajax добавьте свое имя формы в качестве префикса в данные!

data : {
    "my_form" : {
       "field_one" : "field_one_value"
       ...
    }
}
1

Я столкнулся с этой ошибкой и обнаружил, что забыл "обработать" запрос. Удостоверьтесь, что у вас это есть...

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()) {
        ...
1

Да это правильно, что он говорит 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;
}
  • 1
    Или: $ form-> getErrors (true)
0

Для Symfony ( >= 3.2 - 4) вы можете использовать:

foreach($form->getErrors(true, false) as $er) {
    print_r($er->__toString());
}

чтобы увидеть ошибки.

  • 0
    Я не думаю, что это хорошая практика - использовать метод "magic" __toString() напрямую. Проще непосредственно привести объект в строку, как уже предлагал Адам.
  • 1
    Конечно, но, если вы хотите увидеть, что не так без слишком большого количества кода, это может помочь.
Показать ещё 1 комментарий
0

Похоже, у вас есть проблема проверки. Форма не подтверждается при отправке. Я собираюсь предположить, что вы используете аннотации для вашей проверки. Убедитесь, что у вас это в верхней части объекта.

use Symfony\Component\Validator\Constraints as Assert;

а также это выше каждого свойства

/**      
 * @Assert\NotBlank()      
 */

NotBlank() можно изменить на любое ограничение, соответствующее вашим потребностям.

Более подробную информацию о проверке можно найти по адресу: http://symfony.com/doc/current/book/validation.html

Дополнительную информацию о ограничениях Assert можно найти по адресу: http://symfony.com/doc/current/book/validation.html#constraints

  • 0
    Я работаю с MongoDB, поэтому у меня нет юридических лиц, но есть документы. И уже есть эта строка в моем файле класса документа, в противном случае я получил еще одну ошибку PHP или предупреждение;) Я полагаю, моя ошибка приходит с этой аннотацией, потому что у меня есть поля файлов в моей форме ... Я попробую это позже. Спасибо !

Ещё вопросы

Сообщество Overcoder
Наверх
Меню