[Symfony Validator] 在驗證以前初始化對象

這是一個不常見的功能,用於在對象驗證以前作某種操做,例如更新對象、讀取對象元數據 (metadata)。要使用此功能,實現 ObjectInitializerInterface 接口便可,下面是一個示例。php

一個包含了 emailusername 屬性的對象,咱們稱它爲 AcmeUserhtml

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

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

    // ...
}

只設置 email 屬性並提交驗證,username 字段違反了驗證規則:git

$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 接口,在驗證以前改變 usernamegithub

// 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 屬性已經過驗證規則:code

$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 系統,則須要手動爲它打上標籤:symfony

# config/services.yaml

services:
    App\Validator\AcmeUserInitializer
        tags: [ 'validator.initializer' ]
相關文章
相關標籤/搜索