集合
当底层数据是一个集合(即,一个数组或一个实现了 Traversable
和 ArrayAccess
的对象)时,会使用此约束,但您希望以不同的方式验证该集合的不同键。例如,您可以使用 Email
约束验证 email
键,并使用 Range
约束验证集合的 inventory
键。
此约束还可以确保某些集合键存在,并且额外的键不存在。
另请参阅
如果您想验证集合的所有元素都是唯一的,请使用 Unique constraint。
应用于 | 属性或方法 |
类 | 集合 |
验证器 | CollectionValidator |
基本用法
Collection
约束允许您单独验证集合的不同键。以下示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// src/Entity/Author.php
namespace App\Entity;
class Author
{
protected array $profileData = [
'personal_email' => '...',
'short_bio' => '...',
];
public function setProfileData($key, $value): void
{
$this->profileData[$key] = $value;
}
}
要验证 profileData
数组属性的 personal_email
元素是否是有效的电子邮件地址,以及 short_bio
元素是否不为空白且长度不超过 100 个字符,您可以执行以下操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
// src/Entity/Author.php
namespace App\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class Author
{
#[Assert\Collection(
fields: [
'personal_email' => new Assert\Email,
'short_bio' => [
new Assert\NotBlank,
new Assert\Length(
max: 100,
maxMessage: 'Your short bio is too long!'
)
]
],
allowMissingFields: true,
)]
protected array $profileData = [
'personal_email' => '...',
'short_bio' => '...',
];
}
字段的存在与缺失
默认情况下,此约束验证的内容不仅仅是集合中的各个字段是否通过了它们分配的约束。实际上,如果集合中缺少任何键,或者集合中存在任何无法识别的键,则会抛出验证错误。
如果您希望允许集合中缺少键,或者您希望允许集合中存在“额外”键,则可以分别修改 allowMissingFields 和 allowExtraFields 选项。在上面的示例中,allowMissingFields
选项设置为 true,这意味着如果 $personalData
属性中缺少 personal_email
或 short_bio
元素中的任何一个,则不会发生验证错误。
必需和可选字段约束
集合中字段的约束可以包装在 Required
或 Optional
约束中,以控制它们应该始终应用 (Required
) 还是仅在字段存在时应用 (Optional
)。
例如,如果您想要求 profileData
数组的 personal_email
字段不为空白且是有效的电子邮件,但 alternate_email
字段是可选的,但如果提供,则必须是有效的电子邮件,您可以执行以下操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
// src/Entity/Author.php
namespace App\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class Author
{
#[Assert\Collection(
fields: [
'personal_email' => new Assert\Required([
new Assert\NotBlank,
new Assert\Email,
]),
'alternate_email' => new Assert\Optional(
new Assert\Email
),
],
)]
protected array $profileData = ['personal_email' => '[email protected]'];
}
即使不将 allowMissingFields
设置为 true,您现在也可以从 profileData
数组中完全省略 alternate_email
属性,因为它被标记为 Optional
。但是,如果 personal_email
字段在数组中不存在,NotBlank
约束仍然会应用(因为它被包装在 Required
中),您将收到约束违规。
当您在嵌套约束中定义组时,它们会自动添加到 Collection
约束本身,以便可以遍历所有嵌套组。以下示例:
1 2 3 4 5 6 7 8
use Symfony\Component\Validator\Constraints as Assert;
$constraint = new Assert\Collection([
'fields' => [
'name' => new Assert\NotBlank(['groups' => 'basic']),
'email' => new Assert\NotBlank(['groups' => 'contact']),
],
]);
这将产生以下配置:
1 2 3 4 5 6 7 8 9 10 11 12 13
$constraint = new Assert\Collection([
'fields' => [
'name' => new Assert\Required([
'constraints' => new Assert\NotBlank(['groups' => 'basic']),
'groups' => ['basic', 'strict'],
]),
'email' => new Assert\Required([
"constraints" => new Assert\NotBlank(['groups' => 'contact']),
'groups' => ['basic', 'strict'],
]),
],
'groups' => ['basic', 'strict'],
]);
默认的 allowMissingFields
选项要求所有组中的字段都存在。因此,当在 contact
组中验证时,$name
可以为空,但键仍然是必需的。如果这不是预期的行为,请显式使用 Optional
约束而不是 Required
。
选项
allowExtraFields
type: boolean
default: false
如果此选项设置为 false
,并且底层集合包含一个或多个未包含在 fields 选项中的元素,则将返回验证错误。如果设置为 true
,则额外的字段是可以的。
allowMissingFields
type: boolean
default: false
如果此选项设置为 false
,并且底层集合中缺少 fields 选项中的一个或多个字段,则将返回验证错误。如果设置为 true
,则 fields 选项中的某些字段在底层集合中不存在是可以的。
extraFieldsMessage
type: string
default: This field was not expected.
如果 allowExtraFields 为 false 并且检测到额外的字段,则显示此消息。
您可以在此消息中使用以下参数:
参数 | 描述 |
---|---|
{{ field }} |
检测到的额外字段的键 |
missingFieldsMessage
type: string
default: This field is missing.
如果 allowMissingFields 为 false 并且底层集合中缺少一个或多个字段,则显示此消息。
您可以在此消息中使用以下参数:
参数 | 描述 |
---|---|
{{ field }} |
在 fields 中定义的缺失字段的键 |