本文目录导读:

我来详细介绍一下Symfony框架中的Form组件和行为验证系统。
Symfony Form 组件
基础表单创建
// src/Form/UserType.php
namespace App\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
class UserType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('username', TextType::class, [
'label' => '用户名',
'attr' => ['placeholder' => '请输入用户名']
])
->add('email', EmailType::class, [
'label' => '邮箱',
'required' => true
])
->add('password', PasswordType::class, [
'label' => '密码'
])
->add('submit', SubmitType::class, [
'label' => '提交'
]);
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => User::class,
'csrf_protection' => true,
'csrf_field_name' => '_token',
]);
}
}
控制器中使用表单
// src/Controller/UserController.php
namespace App\Controller;
use App\Entity\User;
use App\Form\UserType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class UserController extends AbstractController
{
public function register(Request $request): Response
{
$user = new User();
$form = $this->createForm(UserType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// 处理表单数据
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($user);
$entityManager->flush();
return $this->redirectToRoute('user_success');
}
return $this->render('user/register.html.twig', [
'form' => $form->createView(),
]);
}
}
验证系统
实体验证注解
// src/Entity/User.php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Entity(repositoryClass="App\Repository\UserRepository")
*/
class User
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=50)
* @Assert\NotBlank(message="用户名不能为空")
* @Assert\Length(
* min = 3,
* max = 50,
* minMessage = "用户名至少{{ limit }}个字符",
* maxMessage = "用户名最多{{ limit }}个字符"
* )
*/
private $username;
/**
* @ORM\Column(type="string", length=180, unique=true)
* @Assert\NotBlank(message="邮箱不能为空")
* @Assert\Email(
* message = "邮箱格式不正确"
* )
*/
private $email;
/**
* @ORM\Column(type="string")
* @Assert\NotBlank(message="密码不能为空")
* @Assert\Length(
* min = 8,
* minMessage = "密码至少{{ limit }}个字符"
* )
* @Assert\Regex(
* pattern="/^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$/",
* message="密码必须包含字母和数字"
* )
*/
private $password;
// Getters and Setters...
}
自定义验证器
// src/Validator/Constraints/ContainsAlphanumeric.php
namespace App\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
/**
* @Annotation
*/
class ContainsAlphanumeric extends Constraint
{
public $message = '字符串 "{{ string }}" 只能包含字母和数字';
}
// src/Validator/Constraints/ContainsAlphanumericValidator.php
namespace App\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
class ContainsAlphanumericValidator extends ConstraintValidator
{
public function validate($value, Constraint $constraint)
{
if (!preg_match('/^[a-zA-Z0-9]+$/', $value, $matches)) {
$this->context->buildViolation($constraint->message)
->setParameter('{{ string }}', $value)
->addViolation();
}
}
}
表单验证组
// 定义验证组
/**
* @ORM\Column(type="string")
* @Assert\NotBlank(groups={"registration", "update"})
* @Assert\Length(
* min = 8,
* groups={"registration"}
* )
*/
private $password;
// 在表单中使用验证组
class ChangePasswordType extends AbstractType
{
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'validation_groups' => ['update'],
]);
}
}
// 控制器中动态设置验证组
public function update(Request $request, User $user): Response
{
$form = $this->createForm(UserType::class, $user, [
'validation_groups' => ['update']
]);
// ...
}
手动验证
use Symfony\Component\Validator\Validator\ValidatorInterface;
class UserService
{
private $validator;
public function __construct(ValidatorInterface $validator)
{
$this->validator = $validator;
}
public function validateUser(User $user): array
{
$errors = $this->validator->validate($user);
if (count($errors) > 0) {
$errorMessages = [];
foreach ($errors as $error) {
$errorMessages[] = $error->getMessage();
}
return $errorMessages;
}
return [];
}
}
模板中显示表单和错误
{# templates/user/register.html.twig #}
{% extends 'base.html.twig' %}
{% block body %}
<h1>用户注册</h1>
{{ form_start(form) }}
{% for error in form.vars.errors %}
<div class="alert alert-danger">{{ error.message }}</div>
{% endfor %}
<div class="form-group">
{{ form_label(form.username) }}
{{ form_widget(form.username) }}
{{ form_errors(form.username) }}
</div>
<div class="form-group">
{{ form_label(form.email) }}
{{ form_widget(form.email) }}
{{ form_errors(form.email) }}
</div>
<div class="form-group">
{{ form_label(form.password) }}
{{ form_widget(form.password) }}
{{ form_errors(form.password) }}
</div>
{{ form_widget(form.submit) }}
{{ form_end(form) }}
{% endblock %}
常见的验证约束集合
// 常用验证约束
use Symfony\Component\Validator\Constraints as Assert;
class Product
{
/**
* @Assert\NotBlank(message="标题不能为空")
* @Assert\Length(min=3, max=255)
*/
private $title;
/**
* @Assert\NotNull()
* @Assert\Positive(message="价格必须大于0")
* @Assert\Type("numeric")
*/
private $price;
/**
* @Assert\Date()
* @Assert\GreaterThan("today")
*/
private $publishDate;
/**
* @Assert\File(
* maxSize = "5M",
* mimeTypes = {"image/jpeg", "image/png"},
* mimeTypesMessage = "只允许上传JPEG或PNG图片"
* )
*/
private $image;
/**
* @Assert\Choice(
* choices = {"draft", "published", "archived"},
* message = "请选择有效的状态"
* )
*/
private $status;
/**
* @Assert\NotNull()
* @Assert\All({
* @Assert\Type("string"),
* @Assert\NotBlank()
* })
*/
private $tags;
}
Symfony的Form组件和验证系统提供了强大且灵活的表单处理和数据验证功能,能够满足大部分Web应用的开发需求。