我在项目中使用的是Symfony验证程序和Symfony服务容器,但没有使用完整的Symfony框架。
我编写了一个自定义验证器,该验证器需要一些依赖项作为构造函数参数提供。
该Symfony的文档描述了如何配置验证的服务,这是我已经成功完成的方法。但随后便可以使用validator.constraint_validator
service标签了,我怀疑这是将它们粘合在一起的。
该服务标签似乎特定于使用完整的Symfony Framework时-当我添加此标签时,Symfony Validator不会神奇地加载我的自定义验证器(毫不奇怪)。
那么,如何链接验证器和服务容器组件?还是有其他让Symfony Validator为我的客户验证器加载依赖项的策略?
没错,这个标记(validator.constraint_validator
)是由编译器传递处理的Symfony/FrameworkBundle
。如果您不想使用此捆绑包,但想将DI容器与验证器链接,则应重新实现此过程。
首先,我们需要一个ConstraintValidatorFactoryInterface实例。默认实现只是寻找一个类,其名称由约束的validatedBy()返回。从FrameworkBundle实施时,将validatedBy()的结果视为服务标识符/标签别名,并从容器中获取此服务。我们的实现应执行以下操作:
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Validator\ConstraintValidatorFactoryInterface;
use Symfony\Component\Validator\Constraint;
class ContainerConstraintValidatorFactory implements ConstraintValidatorFactoryInterface
{
private $container;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
public function getInstance(Constraint $constraint)
{
// Simplified implementation, just for example:
return $this->container->get($constraint->validatedBy());
}
}
例如,假设我们有一些自定义验证约束和带有某些依赖项的验证器类:
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
class CustomConstraint extends Constraint
{
public $message = 'Oops!';
public function validatedBy()
{
return 'validator.custom';
}
}
class CustomConstraintValidator extends ConstraintValidator
{
private $dependency;
public function __construct($dependency)
{
$this->dependency = $dependency;
}
public function validate($value, Constraint $constraint)
{
if (rand() % 2 === 0) {
$this->context
->buildViolation($constraint->message)
->addViolation();
}
}
}
接下来,我们将约束验证器作为服务注册,其ID与validatedBy()
来自相关约束对象的方法的结果相同。我们通过该工厂创建与容器相关的验证器服务的实例。以相同方式注册的所有约束验证器将可用。
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Validator\Validation;
$container = new ContainerBuilder();
$container->register(
'validator.custom',
new CustomConstraintValidator('Some dependency value')
);
$validatorBuilder = Validation::createValidatorBuilder();
$validatorBuilder->setConstraintValidatorFactory(
new ContainerConstraintValidatorFactory($container)
);
$validator = $validatorBuilder->getValidator();
$violations = $validator->validate('test value', [
new CustomConstraint()
]);
它可以工作,但是我建议考虑FrameworkBundle
不要重新发明轮子。您可以将其配置为仅使用所需的东西。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句