Symfony表单验证与验证器服务

Ivo*_*eek 12 php forms validation symfony

我有一个奇怪的问题,我想我错过了一些东西.

我正在使用Symfony 2.7,我正在使用用户密码更新功能.

我有一个具有多个属性的用户实体(Extends FosUserBundle用户实体).其中一个是plainPassword(当然没有持久化到DB).

user.php的

...

/**
 * @ORM\Table(name="prefix_users")
 * @ORM\Entity(repositoryClass="UserRepository")
 *
 * @UniqueEntity(fields={"email"}, message="unique", groups={"registration"})
 * @UniqueEntity("username", message="unique", groups={"registration"})
 *
 * @ExclusionPolicy("all")
 */
class User extends BaseUser
{

...

    /* @var string
     *
     * @Assert\NotBlank(message="blank",groups={"accountUpdate", "passwordUpdate"})
     * @Assert\Length(min=8, minMessage="short", max=4096, maxMessage="long")
     */
    protected $plainPassword;
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我正在使用注释来验证我的属性.我也使用验证组来确保只验证正确的属性.

我创建了一个表单

UserUpdatePasswordType.php

class UserUpdatePasswordType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('plainPassword', 'repeated', array(
            'type' => 'password',
            'invalid_message' => 'password_mismatch',
        ));
    }

    /**
     * @param OptionsResolverInterface $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'My\Bundle\UserBundle\Entity\User',
            'csrf_protection' => false,
            'intention' => 'resetting',
            /**
             * Need to add method to prevent this form from bein marked as invalid.
             * @see http://sroze.io/2013/10/30/symfony2-form-patch-requests-and-handlerequest-form-never-valid/
             */
            'method' => 'PATCH'
        ));
    }
Run Code Online (Sandbox Code Playgroud)

我正在使用FOSRestBundle构建一个restful API,如果表单验证失败,我想提供一个漂亮而干净的输出.

据我所知,我可以通过两种方式验证表单:

  1. $ formErrors = $ this-> get('validator') - > validate($ user,null,['passwordUpdate']);
  2. $ form-> isValid()并获取错误$ form-> getErrors()

现在奇怪的部分来了,上面的两种方法给出了不同的验证错误.

请求参数

user_update_password[plainPassword][first]:sffsdfdsfds
user_update_password[plainPassword][second]:fdsfdsfsd
Run Code Online (Sandbox Code Playgroud)

响应来自$ formErrors = $ this-> get('validator') - > validate($ user,null,['passwordUpdate']); 响应不正确,因为plainPassword不是空白​​.

{
      "property_path": "plainPassword",
      "message": "blank"
}
Run Code Online (Sandbox Code Playgroud)

响应形式$ form-> isValid()似乎看起来更好

"form": {
      "children": {
        "plainPassword": {
          "children": {
            "first": {
              "errors": [
                "password_mismatch"
              ]
            },
            "second": {}
          }
        }
      }
    },
    "errors": []
Run Code Online (Sandbox Code Playgroud)

我能看到的唯一区别是我没有在$ form-> isValid()中提供验证组名称.

为什么我会得到不同的结果,我该怎么做才能解决?我可以为$ form-> isValid()提供验证组名称,还是应该修复$ validator-> validate代码的问题?

我很想知道如何在其他基于Symfony2的API中管理它...

Mac*_*ski 5

差异有三个原因.

  1. 你可能不从一组数据request,以model通过验证服务时.使用$form->submit($request)的安全代理数据二传手
  2. 您不使用表单中的验证组(执行setDefaults)BTW.在@Assert\Length将组添加到此批注或将验证组添加Defaultservice/form验证器数组之前,将不会使用您的方法
  3. repeated在表单中使用了type,Constraints与模型相比还有其他类型Constraints.表单验证器检查属于通过的验证组的模型和表单约束(默认情况下使用"默认"组)


Dmi*_*nko 2

实际上,还有另一个区别(除了使用验证组之外)。当您使用表单(而不仅仅是验证器)时,会涉及到“重复”类型。

验证

重复字段的关键功能之一是内部验证(您不需要执行任何操作来设置它),它强制两个字段具有匹配的值。如果两个字段不匹配,则会向用户显示错误。

因此,实际上在一种情况下您使用了附加约束,而在另一种情况下则没有。毫不奇怪,验证会给出不同的结果。

因此,在您的情况下,我可能会自己实现“重复”用户对象中的密码,并使用验证器服务。

我看到的另一个选择是使用 Form 对象来验证用户,但这不是一种干净清晰的 API 制作方法。