Symfony不维护固定Constraints清单,应通过php bin/console debug:validator查看当前项目所有已注册约束,含第三方和自定义;@Assert\Email推荐mode="strict";@Assert\Collection仅校验关联数组或DTO;自定义Constraint的配置项必须为public属性。

没有“完整列表”这回事——Symfony官方不维护一个固定数量的Constraints清单,它随版本演进、Bundle扩展和自定义约束持续增长;你真正该关注的是“哪些约束解决当前问题”,而不是数有多少个。
查内置约束别翻文档,用命令行直接看
运行 php bin/console debug:validator 能列出当前项目中所有已注册的约束类(含第三方Bundle提供的),比查官网更准,也包含你本地写的自定义约束。输出里每行是一个Constraint类全名,比如 Symfony\Component\Validator\Constraints\NotBlank。注意:只有被自动加载或显式注册的才会出现,单纯 use 但没用到的不会列出来。
- 想过滤邮箱相关?加
| grep Email(Linux/macOS)或findstr Email(Windows) - 发现某个约束报错说“class not found”?说明它所属的Bundle没装,比如
@Assert\Iban需要symfony/intl - 这个命令不显示参数说明——要看具体用法,得查对应类的PHPDoc或源码里的
$options属性声明
@Assert\Email 的 mode 参数到底怎么选
@Assert\Email 默认用 mode="html5",它只校验基本格式(a@b.c 算合法),不查MX记录也不验证TLD。生产环境几乎总是该切到 mode="strict":
/** * @Assert\Email(mode="strict") */ public $email;
-
mode="loose"已废弃,别用 -
mode="strict"会调用filter_var($value, FILTER_VALIDATE_EMAIL),比HTML5模式严格得多,但仍不保证邮箱真实存在 - 如果需要验证邮箱域名是否可投递(比如查MX),得自己写Callback或自定义Constraint,框架不提供
Collection 约束不是“数组校验”,而是“结构校验”
@Assert\Collection 常被误当成校验普通数组,其实它只对关联数组(即键值对)或DTO对象生效,且必须明确定义每个键的约束:
/**
* @Assert\Collection(
* fields={
* "name" = @Assert\NotBlank(),
* "price" = @Assert\Range(min=0.01)
* }
* )
*/
public array $productData;
- 传入索引数组
["foo", "bar"]会直接跳过验证,不报错也不校验 - 传入
["name" => "", "price" => -5]才触发两条错误 - 想校验“数组长度”,得额外加
@Assert\Count;想校验“每个元素是字符串”,得用@Assert\All包一层@Assert\Type("string")
自定义Constraint里 public 属性才是配置项
写自定义约束时,所有能通过注解传进来的参数(比如 @MyConstraint(threshold=3)),必须声明为 public 属性,不能是 private 或 protected:
class MyConstraint extends Constraint
{
public $threshold = 1; // ✅ 正确:会被自动注入
private $internalFlag = false; // ❌ 这个永远不会被设值
}
- 框架用反射把注解里的键值对直接赋给同名
public属性,不走构造函数 - 如果属性名和注解参数名不一致(比如想用
minLength但属性叫$min),得在getTargets()或validatedBy()之外,靠options数组中转,但不如直接命名一致来得干脆 - 忘记声明
public $message?那你没法自定义错误提示,只能用默认文本
真正容易被忽略的点是:约束本身不执行逻辑,它只是个配置容器;验证逻辑全在对应的 ConstraintValidator 里。写错一个 public 属性名,或者漏掉 validatedBy() 返回值,验证就会静默失效——连错误都不会抛,表单就“假装通过”了。


















