web-dev-qa-db-ja.com

エラーのないSymfony2の無効なフォーム

Symfony2で生成されたCRUDフォームに問題があります。 (MongoDB Documentsを使用していますが、これは関連しているとは思いません)

コントローラーのcreateAction()メソッドで、フォームの結果をデバッグするとき:

_$form->isValid() // returns false

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

そのため、twigテンプレートでform_errors(form)を使用して何も取得しません($form->getErrors() empty returnのために正常に見えます)

そして、書き込まれた値はフォームで置き換えられません...

誰にもアイデアがありますか?

60
Flo Schild

最初に理解することは、フォームではなくモデルで検証が行われることです。フォームにエラーが含まれる可能性がありますが、検証されないプロパティにマップされたフィールドがある場合のみです。したがって、フォームに無効なフィールド(フォームにないプロパティに対するNotNullアサーション)が含まれていない場合、エラーは表示されません。

2つ目は、$form->getErrors()はそのレベルのエラーのみを表示することです。各フォームの子には独自のエラーを含めることができます。したがって、エラーを確認する場合は、フィールドをループして、各フィールドでgetErrorsを呼び出す必要があります。 FormクラスのgetErrorsメソッドは、そのように欺くことができます。

61
Peter Kruithof

フォームをデバッグするには、$form->getErrorsAsString()の代わりに$form->getErrors()を使用します。

$form->getErrorsAsString()はフォームのデバッグにのみ使用する必要があります... $form->getErrors()の場合ではない各子要素のエラーが含まれます。

ピーターが言及したように、$form->getErrors()は、子フォームのすべてのエラーの合計を返しません。

フォームが無効になり、空の配列を返すgetErrors()がどのように発生するかを理解するには、symfonyフォームクラスの isValid() メソッドを見てください。ご覧のとおり、フォームが無効なケースは2つあります。最初のケースは一般的なフォームのテストで、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()自体はすべてのエラーを返しません。多くの子要素を持つフォームを考えると、CSRFが正しくない場合、通常はCSRFエラーのある$ form-> getErrors()があります。

62
Mick

Symfony 2.6の更新

Symfony2のバージョンに応じて:

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をアクティブにしている場合は、DebugBundle(開発環境)関数を使用することもできます。

_dump((string) $form->getErrors());     // Main errors
dump((string) $form->getErrors(true)); // Main and child errors
_
53
COil

私は同じ問題を抱えています。私にとって、フォームは有効ではありませんでしたが、$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

18
micmia

Symfony(> = 3.2-4)の場合、次を使用できます。

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

明らかにエラーを確認します。

6
Somen Diégo

Symfony 3以降のドキュメントでは、新しい実装を使用する必要があります。

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

これにより、すべてのエラーが1つの文字列として返されます。

4
Adam

私にとっては、送信ボタンがあってもフォームは送信されませんでした。問題を解決するコードを追加しました

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

はい、それは正しいです、それが言うこと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;
}
2
ederrafo

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データ(配列を意味する)内でフォームの名前を見つけられませんでした。

通常の方法でフォームをレンダリングすると、各フィールドには、フォームの名前がプレフィックスとして名前属性my_form[child_field_name]に含まれます。

Ajaxを使用する場合、フォームの名前をプレフィックスとしてdatasに追加してください!

data : {
    "my_form" : {
       "field_one" : "field_one_value"
       ...
    }
}
2
Stphane

このエラーに遭遇し、リクエストを「処理」するのを忘れていたことがわかりました。あなたがそれを持っていることを確認してください...

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
Layton Everson

検証に問題があるように見えます。フォームは送信時に検証されません。検証に注釈を使用していると仮定します。これがエンティティの上部にあることを確認してください。

_use Symfony\Component\Validator\Constraints as Assert;
_

また、各プロパティの上にこれ

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

NotBlank()は、ニーズに合わせて任意の制約に変更できます。

検証の詳細については、次を参照してください。 http://symfony.com/doc/current/book/validation.html

アサート制約の詳細については、次を参照してください。 http://symfony.com/doc/current/book/validation.html#constraints

0
Dave Mascia