Php 如何验证Symfony表单输入MoneyType?

Php 如何验证Symfony表单输入MoneyType?,php,forms,validation,symfony,Php,Forms,Validation,Symfony,如何使用验证表单帖子 这已经够糟糕的了,但更糟糕的是,不管输入什么,比如“asdf”,响应总是:发布的有效表单。如何获得有用的错误消息,指示用户需要输入有效的金额,例如“43.21” 我尝试了添加选项上的'error\u bubbling'=>true,twig视图中的{form\u errors(form)},以及所建议的控制器中的$form->getErrors(),但这些都是空的,因为无论用户输入如何,$form->isValid()始终返回true 项目结构: scratch.php

如何使用验证表单帖子

这已经够糟糕的了,但更糟糕的是,不管输入什么,比如“asdf”,响应总是:
发布的有效表单。
如何获得有用的错误消息,指示用户需要输入有效的金额,例如“43.21”

我尝试了添加选项上的
'error\u bubbling'=>true
,twig视图中的
{form\u errors(form)}
,以及所建议的控制器中的
$form->getErrors()
,但这些都是空的,因为无论用户输入如何,
$form->isValid()
始终返回true


项目结构:
scratch.php
composer.json

您必须向表单字段附加一个或多个约束,如下所示:

use Symfony\Component\Validator\Constraints\Regex;

$formBuilder->add("amount", MoneyType::class, [
  'currency' => 'USD',
  'error_bubbling' => true,
  'constraints' => [
    new Regex(array('pattern'=>'/\d+(\.\d+)?/','message'=>'must be numeric')),
  ]
]);
然后,如果违反了约束,将显示消息“必须是数字”,并且您的表单将无效

此处定义了内置约束:

验证使用说明如下:

我发现我错过了比赛

然后我需要将表单添加到表单工厂

use Symfony\Component\Form\Extension\Validator\ValidatorExtension;

// create your form factory as normal
$formFactory = Forms::createFormFactoryBuilder()
    ...
    ->addExtension(new ValidatorExtension($validator))
    ...
这当然需要
composer需要symfony/validator

所以,我不需要

  • $form->getErrors(true)
  • 'error\u bubbling'=>true
  • {{form_errors(form)}}

scratch.php
composer.json

致命错误:未捕获异常“Symfony\Component\options resolver\exception\UndefinedOptionsException”,消息“选项“constraints”不存在。
验证程序组件是否仍存在此错误?感谢您再次签入,但此答案实际上存在很多问题。1) 您的
use
语句有输入错误,应该是复数
Constraint
而不是单数
Constraint
。2) 它无法捕获字母字符-可能是因为默认的MoneyType验证器胜过它。3) 它在一个有效的数量上失败,例如“12.34”,并抛出一个PHP警告
preg_match():分隔符不能是字母数字或反斜杠
您已经修复了1和3,但它仍然没有抛出
“必须是数字”
消息。它会以默认值
停止。此值无效。
“此值无效”是否写入{form_errors(form)}块?奇怪“scratch.php”文件的用途是什么?为什么不改为使用控制器文件?我只是想问一下,因为“scratch.php”文件中有很多似乎不必要的代码。。。您还将其放在文件夹
pub
下,这不是Symfony标准。也许你这样创建项目是有原因的——你能解释一下吗?@AlvinBunk Standalone最小、完整、可验证的示例。我不是在使用框架,而是在用Symfony测试waters,因为组件被认为是模块化的。为什么不在您的用例中使用NumberType字段而不是MoneyType?@Alsatian,因为我处理的是货币,而不仅仅是数字,我想利用这个类的其他属性,比如国际货币兑换的包装器,而输入类型号实际上是我的核心问题。
{{ form_start(form) }}

    {{ form_errors(form) }}

    {{ form_widget(form) }}

    <input type="submit" />

{{ form_end(form) }}
{
    "require": {
        "symfony/form": "^3.1",
        "symfony/twig-bridge": "^3.1",
        "symfony/translation": "^3.1",
        "symfony/http-foundation": "^3.1"
    }
}
use Symfony\Component\Validator\Constraints\Regex;

$formBuilder->add("amount", MoneyType::class, [
  'currency' => 'USD',
  'error_bubbling' => true,
  'constraints' => [
    new Regex(array('pattern'=>'/\d+(\.\d+)?/','message'=>'must be numeric')),
  ]
]);
use Symfony\Component\Validator\Validation;

// Set up the Validator component
$validator = Validation::createValidator();
use Symfony\Component\Form\Extension\Validator\ValidatorExtension;

// create your form factory as normal
$formFactory = Forms::createFormFactoryBuilder()
    ...
    ->addExtension(new ValidatorExtension($validator))
    ...
<?php require_once __DIR__.'/../vendor/autoload.php';
use Symfony\Component\Form\Forms;
use Symfony\Component\Form\Extension\Core\Type\MoneyType;
use Symfony\Component\Form\Extension\HttpFoundation\HttpFoundationExtension;
use Symfony\Component\Form\Extension\Validator\ValidatorExtension;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Translation\Translator;
use Symfony\Component\Validator\Validation;
use Symfony\Bridge\Twig\Form\TwigRenderer;
use Symfony\Bridge\Twig\Form\TwigRendererEngine;
use Symfony\Bridge\Twig\Extension\FormExtension;
use Symfony\Bridge\Twig\Extension\TranslationExtension;

// the Twig file that holds all the default markup for rendering forms
// this file comes with TwigBridge
$defaultFormTheme = 'form_div_layout.html.twig';

$appVariableReflection = new \ReflectionClass('\Symfony\Bridge\Twig\AppVariable');
$vendorTwigBridgeDir = dirname($appVariableReflection->getFileName());
// the path to your other templates
$viewsDir = realpath(__DIR__.'/../views');

$twig = new Twig_Environment(new Twig_Loader_Filesystem(array(
    $viewsDir,
    $vendorTwigBridgeDir.'/Resources/views/Form',
)));
$formEngine = new TwigRendererEngine(array($defaultFormTheme));

$twig->addExtension(
    new FormExtension(new TwigRenderer($formEngine))
);

$twig->addExtension(
    new TranslationExtension(new Translator('en'))
);

$formEngine->setEnvironment($twig);

// Set up the Validator component
$validator = Validation::createValidator();

// create your form factory as normal
$formFactory = Forms::createFormFactoryBuilder()
    ->addExtension(new HttpFoundationExtension())
    ->addExtension(new ValidatorExtension($validator))
    ->getFormFactory();

$formBuilder = $formFactory->createBuilder();

$formBuilder->add("amount", MoneyType::class, [
  'currency' => 'USD'
]);

$form = $formBuilder->getForm();

$request = Request::createFromGlobals();

$form->handleRequest($request);

if ($form->isValid()) {

    die('valid form posted.');

}

$form->getErrors(true);

echo $twig->render('form.html.twig', array(
    'form' => $form->createView(),
));
{{ form_start(form) }}

    {{ form_widget(form) }}

    <input type="submit" />

{{ form_end(form) }}
{
    "require": {
        "symfony/form": "^3.1",
        "symfony/twig-bridge": "^3.1",
        "symfony/translation": "^3.1",
        "symfony/http-foundation": "^3.1"
        "symfony/validator": "^3.1"
    }
}