Symfony2 недопустимая форма без ошибок


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

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

$form->isValid() // returns false

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

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

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

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

11 55

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 версия:

в Symfony2.3

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