這是一個不常見的功能,用於在對象驗證以前作某種操做,例如更新對象、讀取對象元數據 (metadata)。要使用此功能,實現 ObjectInitializerInterface 接口便可,下面是一個示例。php
一個包含了 email
和 username
屬性的對象,咱們稱它爲 AcmeUser
:html
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 接口,在驗證以前改變 username
:github
// 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' ]