如何在PHP验证器中为自定义约束传入charAmount可变参数
可行性与具体实现方案
完全可行,这是PHP属性验证器的标准配置方式。以下是具体实现步骤:
1. 更新约束类(HasZeroOrXAmountOfCharacters)
修改约束类,添加可配置的charAmount参数,并通过构造函数接收该参数:
namespace NexusAssert; use Symfony\Component\Validator\Constraint; #[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] class HasZeroOrXAmountOfCharacters extends Constraint { // 定义可配置的字符数量属性 public int $charAmount; // 可自定义的错误提示消息,支持参数替换 public string $message = '该字段必须为空或恰好包含 {{ charAmount }} 个字符。'; public function __construct( int $charAmount, array $options = null, array $groups = null, mixed $payload = null ) { // 调用父类构造函数处理验证组、payload等默认选项 parent::__construct($options, $groups, $payload); // 赋值传入的字符数量参数 $this->charAmount = $charAmount; } // 指定对应的验证器类(遵循Symfony验证器命名约定) public function validatedBy(): string { return static::class . 'Validator'; } }
2. 修改验证器类(HasZeroOrXAmountOfCharactersValidator)
将硬编码的13替换为约束对象的charAmount属性:
namespace NexusAssert; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Exception\UnexpectedTypeException; class HasZeroOrXAmountOfCharactersValidator extends ConstraintValidator { public function validate($value, Constraint $constraint): void { // 确保传入的约束是当前类对应的约束类型 if (!$constraint instanceof HasZeroOrXAmountOfCharacters) { throw new UnexpectedTypeException($constraint, HasZeroOrXAmountOfCharacters::class); } // 空值直接通过验证(如果需要禁止空值可移除此逻辑) if ($value === null || $value === '') { return; } // 验证值的类型是否为字符串 if (!is_string($value)) { throw new UnexpectedTypeException($value, 'string'); } // 使用约束对象中的charAmount参数而非硬编码值 $length = mb_strlen($value); if ($length !== 0 && $length !== $constraint->charAmount) { $this->context->buildViolation($constraint->message) ->setParameter('{{ charAmount }}', $constraint->charAmount) ->addViolation(); } } }
3. 使用带参数的验证器属性
在需要验证的属性上,通过命名参数传入charAmount值(注意PHP属性中使用冒号:而非等号=):
#[NexusAssert\HasZeroOrXAmountOfCharacters(charAmount: 13)] private string $yourProperty;
关键说明
- 属性标记:通过
#[Attribute(...)]声明该类可作为属性使用,并指定适用目标(属性、方法等)。 - 参数传递:构造函数接收
charAmount参数,并将其赋值给类的公共属性,供验证器读取。 - 错误消息:通过
{{ charAmount }}占位符动态替换为传入的参数值,提升消息灵活性。
内容的提问来源于stack exchange,提问作者Jelmer405
相关产品推荐
相关产品推荐

