You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 14:54:29