当前位置: 首页>>技术问答>>正文


Symfony验证表单与映射的虚假表单字段

糖太粽 技术问答 , , 去评论

问题描述

我有一个表单添加额外的字段选项mappedfalse。但是,当我尝试验证我的表单时,它将不会通过这些特定表单字段之上的“此值无效”。这个选项是不是应该绕过验证?

这些表单字段只对填充其他字段有用,我不需要保存或甚至检查它们。

我发现唯一的解决方案是删除所有额外的字段与js在提交按钮点击。

最佳解决办法

这个帖子不是最新的Symfony 2.3

阅读下面的评论

一个新的版本是!

验证Form(Symfony 2.1.2)中的非映射字段

这是一些关于当前在表单中验证无界或非映射字段的方法的一些stackoverflow问题的全局响应。

丰富的Symfony 2生态系统使我们的选择框架成为一个快速发展的工具。 Symfony 2.1版本带来了很多贬低。这意味着Symfony 2.0到2.1.2中的工作将不再适用于Symfony 2.3。有关这方面的更多信息,请阅读UPGRADE FROM Symfony 2.0 to 2.1并在Symfony代码中阅读@deprecated注释。

未绑定字段

构建表单时,通常使用实体,您可以在实体本身将验证确认为验证注释。

namespace Dj\TestBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**    
 * Dj\TestBundle\Entity\Post
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Dj\TestBundle\Entity\PostRepository")
 */
class Post
{
    // ... some code

    /**
    * @var string $title
    * @ORM\Column(name="title", type="string", length=200, nullable=false)
    * @Assert\NotBlank()
    */
    private $title;

    // .. getters and setters
}

但是,有时(通常),您需要在表单中插入一些未映射到模型的字段。

我们的模型示例是这样的:

namespace Dj\TestBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * Dj\TestBundle\Entity\Post
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Dj\TestBundle\Entity\PostRepository")
 */
class Post
{
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**ghjkl
     * @var string $title
     * @ORM\Column(name="title", type="string", length=200, nullable=false)
     * @Assert\NotBlank()
     */
    private $title;

    // ... getters and setters
}

如果我们要在我们的表单中添加一个名为myExtraField的字段,我们会做:

class PostType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('title')
                ->add('myExtraField', 'choice', array(
                        'label' => 'myExtraField option :',
                        'choices' => array(
                            1 => 'Option One',
                            2 => 'Option Wat !'
                        ),
                        'expanded' => true,
                        'mapped' => false
                   ));
    }
    // other methods
}

注意 :

  • 映射替代将在Symfony 2.3中弃用的property_path

  • 您可以通过添加’data’ =>将默认选择的值添加到myExtraField。您的选项数组中的1条目。

示例代码:

$builder->add('title')
    ->add('myExtraField', 'choice', array(
        'label' => 'myExtraField option :',
        'choices' => array(
            1 => 'Option One',
            2 => 'Option Wat !'
        ),
        'data' => 1, // default selected option
        'expanded' => true,
        'mapped' => false
));

如果要验证myExtraField字段,您不能在Post Entity注释中执行此操作,则必须以您的形式执行此操作。

验证非映射字段 – Symfony 2.0方式

2.0的方法是将一个验证器添加到窗体构建器($ builder-> addValidator(..)),但是这个方法已经被弃用了!

namespace Dj\TestBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

// needed namespaces for 2.0 validation
use Symfony\Component\Form\CallbackValidator;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormError;

class PostType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // ... $builder->add()

        // VALIDATING NON MAPPED FIELD Symfony 2.0 way
        /** @var Symfony\Component\Form\CallbackValidator $myExtraFieldValidator **/
        $myExtraFieldValidator = new CallbackValidator(function(FormInterface $form){
          $myExtraField = $form->get('myExtraField')->getData();
            if (empty($myExtraField)) {
              $form['myExtraField']->addError(new FormError("myExtraField must not be empty"));
            }
        });
        // adding the validator to the FormBuilderInterface
        $builder->addValidator($myExtraFieldValidator);
    }
    // ... other methods
}

这当前正在验证myExtraField字段,BUT $ builder-> addValidator将死于Symfony 2.3!

前向兼容代码

UPGRADE FROM Symfony 2.0 to 2.1所述,由于FormValidatorInterface已被弃用,我们现在必须将验证闭包函数传递给绑定到FormEvents :: POST_BIND事件的事件监听器。

这是代码。

namespace Dj\TestBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

// needed namespaces for 2.1 validation
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormError;

class PostType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // ... $builder->add()

        // VALIDATING NON MAPPED FIELD Symfony 2.1.2 way (and forward)
        /** @var \closure $myExtraFieldValidator **/
        $myExtraFieldValidator = function(FormEvent $event){
            $form = $event->getForm();
            $myExtraField = $form->get('myExtraField')->getData();
            if (empty($myExtraField)) {
              $form['myExtraField']->addError(new FormError("myExtraField must not be empty"));
            }
        };

        // adding the validator to the FormBuilderInterface
        $builder->addEventListener(FormEvents::POST_BIND, $myExtraFieldValidator);
    }
    // ... other methods
}

这一点可以通过一些Sf大师的帮助来改善,但是现在它以前向兼容的方式验证未绑定的表单域。

希望帮助我们解脱一些人。

大卫

次佳解决办法

As I mentionned in a question on a similar topicsince Symfony 2.1, you should use the ‘constraints’ option to add validation to your un-mapped fields:

use Symfony\Component\Validator\Constraints\MinLength;
use Symfony\Component\Validator\Constraints\NotBlank;

$builder
    ->add('firstName', 'text', array(
        'constraints' => new MinLength(3),
    ))
    ->add('lastName', 'text', array(
        'constraints' => array(
            new NotBlank(),
            new MinLength(3),
        ),
    ))
;

希望它会帮助任何像我这样失去了一些时间的人…

第三种解决办法

如果您已经在使用约束,那么可以这么做:

$builder
    ->add('new', 'repeated', array(
            'type' => 'password',
            'required'          => true,                    
            'invalid_message' => 'crmpicco.status.password_mismatch',
            'constraints'       => array(
                new NotBlank(),
                new Assert\Length([
                    'min'        => 2,
                    'max'        => 50,
                    'minMessage' => 'Your first name must be at least 2  characters long',
                    'maxMessage' => 'Your first name cannot be longer than 2 characters',
                ])
            )
        ))
    ->add('save', 'submit', array(
            'label' => 'password.form.fields.save',
        ))
    ;

参考文献

注:本文内容整合自google/baidu/bing辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:gxnotes#qq.com(#替换为@)。

本文由《共享笔记》整理, 博文地址: https://gxnotes.com/article/160755.html,未经允许,请勿转载。
Go