本文目录导读:

我来详细介绍 Symfony Form 中的算术验证方法。
基础算术验证方法
使用内置约束
use Symfony\Component\Validator\Constraints as Assert;
class Product
{
#[Assert\Range(
min: 10,
max: 100,
notInRangeMessage: '数值必须在 {{ min }} 到 {{ max }} 之间',
)]
private float $price;
#[Assert\Positive(message: '数值必须为正数')]
#[Assert\LessThan(value: 1000)]
private float $quantity;
}
自定义算术验证器
// src/Validator/ArithmeticValidator.php
namespace App\Validator;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
class ArithmeticValidator extends ConstraintValidator
{
public function validate($value, Constraint $constraint)
{
if (!$constraint instanceof Arithmetic) {
throw new UnexpectedTypeException($constraint, Arithmetic::class);
}
if (null === $value || '' === $value) {
return;
}
// 自定义算术验证逻辑
if ($value < $constraint->min || $value > $constraint->max) {
$this->context->buildViolation($constraint->message)
->setParameter('{{ value }}', $value)
->setParameter('{{ min }}', $constraint->min)
->setParameter('{{ max }}', $constraint->max)
->addViolation();
}
}
}
// src/Validator/Arithmetic.php
namespace App\Validator;
use Symfony\Component\Validator\Constraint;
#[Attribute]
class Arithmetic extends Constraint
{
public string $message = '数值 {{ value }} 必须在 {{ min }} 到 {{ max }} 之间';
public float $min = 0;
public float $max = 100;
public function __construct(
?float $min = null,
?float $max = null,
?string $message = null,
?array $groups = null,
$payload = null
) {
parent::__construct($groups, $payload);
$this->min = $min ?? $this->min;
$this->max = $max ?? $this->max;
$this->message = $message ?? $this->message;
}
}
复杂算术验证示例
// src/Form/Type/OrderType.php
namespace App\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\NumberType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints as Assert;
class OrderType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('quantity', NumberType::class, [
'label' => '数量',
'constraints' => [
new Assert\NotBlank(),
new Assert\Type(['type' => 'numeric', 'message' => '请输入有效的数字']),
]
])
->add('unitPrice', NumberType::class, [
'label' => '单价',
'constraints' => [
new Assert\NotBlank(),
new Assert\Positive(),
]
])
->add('discount', NumberType::class, [
'label' => '折扣率',
'constraints' => [
new Assert\Range([
'min' => 0,
'max' => 100,
'notInRangeMessage' => '折扣率必须在 {{ min }}% 到 {{ max }}% 之间',
])
]
])
->add('submit', SubmitType::class, ['label' => '提交订单']);
// 添加事件监听器进行复杂验证
$builder->addEventListener(FormEvents::SUBMIT, function (FormEvent $event) {
$data = $event->getData();
$form = $event->getForm();
// 计算总价
$totalPrice = $data->getQuantity() * $data->getUnitPrice() * (1 - $data->getDiscount() / 100);
// 验证总价
if ($totalPrice < 0) {
$form->get('quantity')->addError(new FormError('订单总价不能为负数'));
}
if ($totalPrice > 10000) {
$form->addError(new FormError('订单总价不能超过 10,000 元'));
}
// 验证折扣合理性
if ($data->getDiscount() > 50 && $data->getQuantity() < 10) {
$form->get('discount')->addError(new FormError('小额订单折扣不能超过 50%'));
}
});
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => Order::class,
]);
}
}
使用DTO进行高级验证
// src/DTO/ArithmeticDTO.php
namespace App\DTO;
use Symfony\Component\Validator\Constraints as Assert;
class ArithmeticDTO
{
#[Assert\NotBlank]
#[Assert\Type('float')]
private float $value;
#[Assert\NotBlank]
#[Assert\Type('float')]
#[Assert\GreaterThanOrEqual(0)]
private float $percentage;
#[Assert\Callback]
public function validateArithmetic(ExecutionContextInterface $context): void
{
// 检查百分比计算
$calculatedValue = $this->value * ($this->percentage / 100);
if ($calculatedValue > $this->value) {
$context->buildViolation('计算结果不能大于原始值')
->atPath('percentage')
->addViolation();
}
// 检查结果是否合理
if ($calculatedValue < 0) {
$context->buildViolation('计算结果不能为负数')
->atPath('value')
->addViolation();
}
}
}
在表单中使用Callback验证
// src/Form/Type/CalculationType.php
namespace App\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\NumberType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Constraints\Callback;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
class CalculationType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('x', NumberType::class)
->add('y', NumberType::class, [
'constraints' => [
new Callback(function ($y, ExecutionContextInterface $context) {
$form = $context->getRoot();
$x = $form->get('x')->getData();
// 验证除法
if ($y !== null && $y == 0 && $x !== null && $x != 0) {
$context->buildViolation('y 不能为零当 x 不为零时')
->addViolation();
}
// 验证百分比
if ($x !== null && $y !== null && $y > $x * 2) {
$context->buildViolation('y 不能超过 x 的两倍')
->addViolation();
}
})
]
]);
}
}
百分比验证示例
// src/Validator/PercentageValidator.php
namespace App\Validator;
class PercentageValidator extends ConstraintValidator
{
public function validate($value, Constraint $constraint)
{
if (null === $value || '' === $value) {
return;
}
// 限制百分比范围
if ($value < 0 || $value > 100) {
$this->context->buildViolation('百分比必须在 0 到 100 之间')
->setParameter('{{ value }}', $value)
->addViolation();
}
// 检查精度
$decimalPlaces = strlen(substr(strrchr($value, '.'), 1));
if ($decimalPlaces > 2) {
$this->context->buildViolation('百分比最多保留两位小数')
->addViolation();
}
}
}
使用示例
// 在控制器中使用
public function createOrder(Request $request): Response
{
$order = new Order();
$form = $this->createForm(OrderType::class, $order);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// 订单验证通过
$this->entityManager->persist($order);
$this->entityManager->flush();
return $this->redirectToRoute('order_success');
}
return $this->render('order/create.html.twig', [
'form' => $form->createView(),
]);
}
这些方法可以帮助你实现各种算术验证需求,从简单的范围验证到复杂的条件计算验证。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播