php - 如何将实例传递给 symfony 表单验证器类?
问题描述
我正在尝试创建一个自定义 symfony 表单验证器约束。我创建了两个类,一个约束和一个验证器,它工作正常。但是我需要将学说 entitymanager 实例传递给验证器类,因为我是独立使用它们而不是框架,我没有 yaml 配置文件。我在验证器类中创建了一个构造函数来拥有 $em,并且在控制器中我有:
->add('email', EmailType::class, [
'constraints' => [
new Assert\Email(['message' => 'invalid.email', 'mode' => 'strict', 'normalizer' => 'trim']),
new Assert\EmailExists($em),
],
]);
但是我没有得到 $em,在我的验证器类中,我该怎么办?我还尝试在主约束类中使用构造函数,然后在验证器中使用parent::construct()
,但仍然无法正常工作。
我也读过这篇文章 How to configure dependencies on custom validator with Symfony Components?但是我没有创建工厂类,而是使用了当前的因子类并使用了这个:
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Validator\ContainerConstraintValidatorFactory;
$container = new ContainerBuilder();
$container
->register('customEmailUniqueEntity', 'EmailExistsValidator')
->addArgument($em);
$validatorBuilder = Validation::createValidatorBuilder();
$validatorBuilder->setConstraintValidatorFactory(
new ContainerConstraintValidatorFactory($container)
);
$validator = $validatorBuilder->getValidator();
$violations = $validator->validate('email address', [
new EmailExists()
]);
if (0 !== count($violations)) {
// there are errors, now you can show them
foreach ($violations as $violation) {
echo $violation->getMessage().'<br>';
}
}
使用此代码,依赖注入和验证都可以正常工作,但是有没有技巧可以将此自定义约束作为表单构建器中的“约束”数组参数而不是手动验证?
->add('email', EmailType::class, [
'constraints' => [
new Assert\Email(['message' => 'invalid.email', 'mode' => 'strict', 'normalizer' => 'trim']),
new Assert\EmailExists($em),
],
]);
使用上面的代码,我无法将 $em 传递给我的自定义验证器的构造函数。有什么技巧可以吗?
编辑:
为了注入学说EntityManager,在EmailExists
课堂上我有:
public function validatedBy()
{
return 'customEmailUniqueEntity';
//return \get_class($this).'Validator';
}
然后我有:
$container = new ContainerBuilder();
$container
->register('customEmailUniqueEntity', 'EmailExistsValidator')
->addArgument($em);
因为如果我从那里返回验证器类,validatedBy()
我无法将 $em 注入验证器的构造函数。有了下面的答案,我使用了:
->addTag('validator.constraint_validator');
但是现在我收到customEmailUniqueEntity
class not found 错误,好像我从 中返回验证器validatedBy()
,注入将不起作用,我该怎么办?我试图返回
public function validatedBy()
{
return 'EmailExists';
//return \get_class($this).'Validator';
}
但是这个,我当然会initialize()
出错。请指教。
编辑2:
我将 addTag 添加到:
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Validator\ContainerConstraintValidatorFactory;
$container = new ContainerBuilder();
$container
->register('customEmailUniqueEntity', 'EmailExistsValidator')
->addArgument($em),
->addTag('validator.constraint_validator');
$validatorBuilder = Validation::createValidatorBuilder();
$validatorBuilder->setConstraintValidatorFactory(
new ContainerConstraintValidatorFactory($container)
);
$validator = $validatorBuilder->getValidator();
$violations = $validator->validate('email address', [
new EmailExists()
]);
if (0 !== count($violations)) {
// there are errors, now you can show them
foreach ($violations as $violation) {
echo $violation->getMessage().'<br>';
}
}
在 EmailExistsValidator 的构造函数中,我有:
var_dump($em);
我在验证器中得到了 $em 对象,所以 $em 被注入并且添加addTag()
没有导致任何错误。如果我取消约束,则不会进行注入validatedBy()
。EmailExists
在我正在做的那种方法中
return `customEmailUniqueEntity;`
因为如果我返回EmailExistsValidator
,注射将不会完成。现在如何使用validator.constraint_validator
或EmailExists()
作为约束形式的数组参数?如果我使用new EmailExists()
,我将获得两个验证器类的 Aguments,因为 $em 不会以这种方式注入。该怎么办?
解决方案
当确定要用于约束的实际验证器时,您的customEmailUniqueEntity
服务将永远不会被考虑在内。ContainerConstraintValidatorFactory
EmailExists
为了让工厂知道哪些服务是约束验证器,您需要使用如下标签对其进行validator.constraint_validator
标记:
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Validator\DependencyInjection\AddConstraintValidatorsPass;
$container = new ContainerBuilder();
$container
->register('customEmailUniqueEntity', 'EmailExistsValidator')
->addArgument($em)
->addTag('validator.constraint_validator');
$container->addCompilerPass(new AddConstraintValidatorPass());
$container->compile();
推荐阅读
- iis - IIS 服务器 url 重写
- python - 如何将调试库“python37_d.lib”带到 Anaconda?
- python - 遍历框架中的所有子小部件并检查小部件的类型
- web-services - 寻找示例或指南或链接以了解 JAX-WS 1.2 项目
- listview - 小部件进入列表视图或颤动中的数据
- reactjs - 包括 id 的 ReactJs 路由路径返回不正确的组件
- c++ - 如何防止 CMAKE 在构建时为共享库创建符号链接(不在安装时)
- github - 仅在阻止拉取请求时手动运行 GitHub Actions
- sql - 在 MS Access 中查询分组数据
- gitlab - 更改 gitlab markdown 美人鱼图大小