這是一個不常見的功能,用於在對象驗證之前做某種操作,例如更新對象、讀取對象元數據(metadata
)。要使用此功能,只需實現 ObjectInitializerInterface 接口即可,下面是一個使用示例。
一個包含了 email
和 username
屬性的對象,我們稱它爲 AcmeUser
:
class AcmeUser
{
/**
* @Assert\NotBlank()
* @Assert\Email()
*/
private $email;
/**
* @Assert\NotBlank()
*/
private $username;
// ...
}
只設置 email
屬性並提交驗證,username
字段違反了驗證規則:
$entity = new AcmeUser();
$entity->setEmail('[email protected]');
$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('[email protected]');
$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) "[email protected]"
// ["username":"App\Entity\AcmeUser":private]=>
// string(10) "siganushka"
// }
註冊標籤
得益於自動配置 (autoconfigure) 選項,默認情況下你並不需要手動註冊標籤,但如果你在 services.yaml
裏顯式的關閉了自動配置,或者你正在編寫一個公開的第三方的 Bundle 系統,則需要手動爲它打上標籤:
# config/services.yaml
services:
App\Validator\AcmeUserInitializer
tags: [ 'validator.initializer' ]