Validator-在验证之前初始化对象

3次阅读

共计 1562 个字符,预计需要花费 4 分钟才能阅读完成。

这是一个不常见的功能,用于在对象验证之前做某种操作,例如更新对象、读取对象元数据(metadata)。要使用此功能,只需实现 ObjectInitializerInterface 接口即可,下面是一个使用示例。

一个包含了 emailusername 属性的对象,我们称它为 AcmeUser

class AcmeUser
{
    /**
     * @Assert\NotBlank()
     * @Assert\Email()
     */
    private $email;

    /**
     * @Assert\NotBlank()
     */
    private $username;

    // ...
}

只设置 email 属性并提交验证,username 字段违反了验证规则:

$entity = new AcmeUser();
$entity->setEmail('siganushka@gmail.com');

$violationList = $validator->validate($entity);

var_dump((string) $violationList);

// string(118) "Object(App\Entity\AcmeUser).username:
//    This value should not be blank. (code c1051bb4-d103-4f74-8988-acbcafc7fdc3)
// "

实现 ObjectInitializerInterface 接口,在验证之前改变 username

// src/Validator/AcmeUserInitializer.php

use App\Entity\AcmeUser;
use Symfony\Component\Validator\ObjectInitializerInterface;

class AcmeUserInitializer implements ObjectInitializerInterface
{public function initialize($object)
    {if (!$object instanceof AcmeUser) {return;}

        list($username, $host) = explode('@', $object->getEmail());
        $object->setUsername($username);
    }
}

再次验证时 username 属性已通过验证规则:

$entity = new AcmeUser();
$entity->setEmail('siganushka@gmail.com');

$violationList = $validator->validate($entity);
if (count($violationList) > 0) {var_dump((string) $violationList);
    exit;
}

var_dump($entity);
exit;

// object(App\Entity\AcmeUser)#368 (2) {//    ["email":"App\Entity\AcmeUser":private]=>
//    string(20) "siganushka@gmail.com"
//    ["username":"App\Entity\AcmeUser":private]=>
//    string(10) "siganushka"
// }

注册标签

得益于自动配置 (autoconfigure) 选项,默认情况下你并不需要手动注册标签,但如果你在 services.yaml 里显式的关闭了自动配置,或者你正在编写一个公开的第三方的 Bundle 系统,则需要手动为它打上标签:

# config/services.yaml

services:
    App\Validator\AcmeUserInitializer
        tags: ['validator.initializer']

正文完
 0