2012-06-26 2 views
50

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

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

$form->isValid() // returns false 

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

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

И письменные значения не заменяются в виде ...

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

+0

Вы можете изменить свой вопрос, включив в него файл validation.xml или аннотации проверки. – MDrollette

ответ

50

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

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

+2

Я не знал этого, спасибо, я думаю, что нашел ответ. Я попробую! –

+2

Если вы это сделали, отметьте это как принятый ответ, чтобы другие люди с этим вопросом тоже могли воспользоваться этим. –

+0

У меня такая же проблема, я использую createForm и добавляю одно текстовое поле. Почему же это создает дочернюю форму ?! У меня есть только одно текстовое поле ... –

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;) Я полагаю, моя ошибка связана с этой аннотацией, потому что у меня есть поля файлов в моей форме ... Я попробую это позже , Спасибо! –

56

Чтобы отладить форму, используйте $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

Большое спасибо за этот anwser. Без этого мне пришлось бы потратить много времени на отладку недопустимого поля. –

+4

$ form-> getErrorsAsString() устарел в Symfony 2.5+ – ChristoKiwi

+0

Очень хорошая точка @ ChristoKiwi! Не стесняйтесь обновлять ответ, если хотите! – Mick

3

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

$request = $this->get('request'); 
if($request->isMethod("POST")){ 
     $form->submit($request); 
     if($form->isValid()){ 
     // now true 
     } 
} 
+0

Выглядит очень странно, разве у вас нет нескольких форм на одной странице? –

+5

Возможно, вам не хватает инструкции ** $ form-> handleRequest ($ this-> getRequest()) **. Он должен быть вызван перед проверкой * isValid() *. –

17

Я только что получил такую ​​же проблему. Для меня форма недействительна, но я не мог получить никаких ошибок, используя $form->getErrors() или $form->getErrorsAsString(). Позже я обнаружил, что забыл передать токен CSRF в форму, чтобы он не был отправлен, а $form->handleRequest($request) ничего не сделал (без проверки). Как я увидел @ ответ ямы, я пытался использовать

$form->submit($request); 

$form->getErrorsAsString(); 

он возвратил ошибку:

ERROR: The CSRF token is invalid. Please try to resubmit the form.

Вот некоторые пояснения в документации Symfony2: http://symfony.com/doc/current/book/forms.html#handling-form-submissions

+0

Спасибо, этот раствор работал для меня – afeef

43

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

Так что в зависимости от вас Symfony2 версия:

die($form->getErrorsAsString()); 

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

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

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

dump((string) $form->getErrors());  // Main errors 
dump((string) $form->getErrors(true)); // Main and child errors 
+2

Спасибо, не заметил! –

+1

Это помогло мне исправить мою проблему, спасибо! (Использование Symfony 2.8) – ChristoKiwi

+1

$ form-> getErrors (true) приятно! –

2

Если вы отправляете ДАННЫЕ через AJAX, вы, возможно, пропустили включить имя формы на ключи DATAS и, следовательно, «жертвы» ...

# 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 (что означает массив).

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

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

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

Да это правильно, что сказать Питер 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; 
} 
+0

Или: $ form-> getErrors (true) –

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

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

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

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

2

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

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

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

+0

Я не думаю, что это хорошая практика, чтобы использовать метод «magic» '__toString()' напрямую. Легче всего передать объект в строку, как уже сказал Адам. –

+1

Конечно, но если вы хотите увидеть, что случилось, не слишком много кодирования, это может помочь. –

+0

'print_r ((string) $ er));' вместо этого кажется мне менее кодирующим;) И даже можно напрямую сбрасывать 'print_r ((string) $ form-> getErrors (true, false));' без итерации , –

Смежные вопросы