PHP项目Symfony form与行为验证

wen PHP项目 2

本文目录导读:

PHP项目Symfony form与行为验证

  1. Symfony Form 组件
  2. 验证系统

我来详细介绍一下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应用的开发需求。

抱歉,评论功能暂时关闭!