Symfony2で生成されたCRUDフォームに問題があります。 (MongoDB Documentsを使用していますが、これは関連しているとは思いません)
コントローラーのcreateAction()メソッドで、フォームの結果をデバッグするとき:
_$form->isValid() // returns false
$form->getErrors() // returns en empty array(0) {}
_
そのため、twigテンプレートでform_errors(form)
を使用して何も取得しません($form->getErrors()
empty returnのために正常に見えます)
そして、書き込まれた値はフォームで置き換えられません...
誰にもアイデアがありますか?
最初に理解することは、フォームではなくモデルで検証が行われることです。フォームにエラーが含まれる可能性がありますが、検証されないプロパティにマップされたフィールドがある場合のみです。したがって、フォームに無効なフィールド(フォームにないプロパティに対するNotNull
アサーション)が含まれていない場合、エラーは表示されません。
2つ目は、$form->getErrors()
はそのレベルのエラーのみを表示することです。各フォームの子には独自のエラーを含めることができます。したがって、エラーを確認する場合は、フィールドをループして、各フィールドでgetErrorsを呼び出す必要があります。 FormクラスのgetErrors
メソッドは、そのように欺くことができます。
フォームをデバッグするには、$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()があります。
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
をアクティブにしている場合は、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());
}
明らかにエラーを確認します。
Symfony 3以降のドキュメントでは、新しい実装を使用する必要があります。
$errors = (string) $form->getErrors(true, false);
これにより、すべてのエラーが1つの文字列として返されます。
私にとっては、送信ボタンがあってもフォームは送信されませんでした。問題を解決するコードを追加しました
$request = $this->get('request');
if($request->isMethod("POST")){
$form->submit($request);
if($form->isValid()){
// now true
}
}
はい、それは正しいです、それが言うこと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;
}
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"
...
}
}
このエラーに遭遇し、リクエストを「処理」するのを忘れていたことがわかりました。あなたがそれを持っていることを確認してください...
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()
*/
_
NotBlank()
は、ニーズに合わせて任意の制約に変更できます。
検証の詳細については、次を参照してください。 http://symfony.com/doc/current/book/validation.html
アサート制約の詳細については、次を参照してください。 http://symfony.com/doc/current/book/validation.html#constraints