企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
{% raw %} # Symfony 验证教程 > 原文: [http://zetcode.com/symfony/validation/](http://zetcode.com/symfony/validation/) Symfony 验证教程展示了如何在 Symfony 应用中验证数据。 在本教程中,我们使用手动验证。 我们不使用教义注解。 ## Symfony Symfony 是一组可重用的 PHP 组件和一个用于 Web 项目的 PHP 框架。 Symfony 于 2005 年发布为免费软件。Symfony 的原始作者是 Fabien Potencier。 Symfony 的灵感来自 Ruby on Rails,Django 和 Spring 框架。 ## Symfony 验证 来自用户的输入必须经过验证。 Symfony 提供了`Validator`组件来执行验证任务。 该组件基于 Java 的 Bean 验证规范。 验证器旨在针对约束验证对象。 约束是对条件为真的断言。 Symfony 具有许多内置约束,包括`NotBlank`,`Email`,`Length`和`Isbn`。 也可以创建自定义约束。 ## Symfony 验证示例 在示例中,我们有一个简单的表单,其中包含两个字段:`name`和`email`。 提交表单后,我们使用 Symfony 的`Validator`手动验证字段。 在示例中,我们使用`Length`,`NotBlank`和`Email`约束。 ### 安装组件 ```php $ composer create-project symfony/skeleton myval $ cd myval ``` 我们创建一个新的 Symfony 项目,然后转到项目目录。 ```php $ composer req maker server --dev ``` 我们安装`symfony/maker-bundle`和`symfony/web-server-bundle`。 这些对于开发模式很有用。 请注意,我们正在使用包的别名。 ```php $ composer req twig annotations ``` 我们安装`twig-bundle`和注解。 注解位于`sensio/framework-extra-bundle`中。 ```php $ composer req validator ``` `symfony/validator`包包含 Symfony 验证工具。 ```php $ composer req security-csrf $ composer req monolog $ composer req property-access ``` 跨站点请求伪造需要`symfony/security-csrf`包,`symfony/monolog-bundle`用于记录日志,`symfony/property-access`用于操纵 PHP 属性。 ### 构建 Symfony 应用 ```php $ php bin/console make:controller HomeController ``` 我们创建一个`HomeController`。 `src/Controller/HomeController.php` ```php <?php namespace App\Controller; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; class HomeController extends AbstractController { /** * @Route("/home", name="home") */ public function index(): Response { return $this->render('home/index.html.twig'); } } ``` 这是一个简单的控制器,可将包含 Web 表单的视图发送给用户。 ```php $ php bin/console make:controller FormController ``` 我们创建一个`FormController`来响应表单提交。 `src/Controller/FormController.php` ```php <?php namespace App\Controller; use Psr\Log\LoggerInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\PropertyAccess\PropertyAccess; use Symfony\Component\Validator\Constraints as Assert; use Symfony\Component\Validator\Validator\ValidatorInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; class FormController extends AbstractController { /** * @Route("/sendForm", name="form") */ public function index(Request $request, ValidatorInterface $validator, LoggerInterface $logger): Response { $token = $request->request->get("token"); if (!$this->isCsrfTokenValid('myform', $token)) { $logger->info("CSRF failure"); return new Response("Operation not allowed", Response::HTTP_OK, ['content-type' => 'text/plain']); } $name = $request->request->get("name"); $email = $request->request->get("email"); $input = ['name' => $name, 'email' => $email]; $constraints = new Assert\Collection([ 'name' => [new Assert\Length(['min' => 2]), new Assert\NotBlank], 'email' => [new Assert\Email(), new Assert\notBlank], ]); $violations = $validator->validate($input, $constraints); if (count($violations) > 0) { $accessor = PropertyAccess::createPropertyAccessor(); $errorMessages = []; foreach ($violations as $violation) { $accessor->setValue($errorMessages, $violation->getPropertyPath(), $violation->getMessage()); } return $this->render('form/violations.html.twig', ['errorMessages' => $errorMessages]); } else { return new Response("Validation passed", Response::HTTP_OK, ['content-type' => 'text/plain']); } } } ``` 在`FormController`中,我们检查 CSRF 令牌,验证表单输入值,并将响应发送回客户端。 > **注意**:为简单起见,我们将验证代码放入控制器中。 在生产应用中,最好将此类代码放在单独的服务类中。 ```php public function index(Request $request, ValidatorInterface $validator, LoggerInterface $logger) { ``` 我们注入了请求对象,验证器对象和记录器对象。 ```php $token = $request->request->get("token"); if (!$this->isCsrfTokenValid('myform', $token)) { $logger->info("CSRF failure"); return new Response("Operation not allowed", Response::HTTP_OK, ['content-type' => 'text/plain']); } ``` 我们检索令牌并使用`isCsrfTokenValid()`方法对其进行验证。 ```php $name = $request->request->get("name"); $email = $request->request->get("email"); $input = ['name' => $name, 'email' => $email]; ``` 我们获取请求输入参数,并将其放入数组中。 ```php $constraints = new Assert\Collection([ 'name' => [new Assert\Length(['min' => 2]), new Assert\NotBlank], 'email' => [new Assert\Email(), new Assert\notBlank] ]); ``` 我们创建约束的集合。 我们可以为单个值分配多个约束。 ```php $violations = $validator->validate($input, $constraints); ``` 我们使用`validate()`方法对照约束条件验证输入数据。 该方法返回可能的违规。 Symfony 验证器返回`ConstraintViolationList`。 我们使用 Symfony 访问器来处理列表。 ```php if (count($violations) > 0) { ``` 我们检查是否有违规行为。 ```php $accessor = PropertyAccess::createPropertyAccessor(); $errorMessages = []; foreach ($violations as $violation) { $accessor->setValue($errorMessages, $violation->getPropertyPath(), $violation->getMessage()); } ``` Symfony `PropertyAccess`用于在将违规消息发送到模板之前对其进行处理。 `ConstraintViolationList`转换为 PHP 数组,其中的键是表单字段,值是错误消息。 稍后使用`for`指令在 Twig 中处理该数组。 ```php return $this->render('form/violations.html.twig', ['errorMessages' => $errorMessages]); ``` 我们在单独的页面中呈现错误消息。 这通常是使用 Flash 消息完成的。 看看 [Symfony 保持表单值教程](/symfony/keepformvalues/)如何使用 Flash。 ```php } else { return new Response("Validation passed", Response::HTTP_OK, ['content-type' => 'text/plain']); } ``` 如果一切正常,我们将发送一条简单消息验证已通过。 `templates/home/index.html.twig` ```php {% extends 'base.html.twig' %} {% block title %}Home page{% endblock %} {% block body %} <form action="sendForm" method="post"> <input type="hidden" name="token" value="{{ csrf_token('myform') }}" /> <div> <label>Name:</label> <input type="text" name="name"> </div> <div> <label>Email</label> <input type="email" name="email"> </div> <button type="submit">Send</button> </form> {% endblock %} ``` 该表格包含两个字段:姓名和电子邮件。 ```php <input type="hidden" name="token" value="{{ csrf_token('myform') }}" /> ``` 它还包含一个隐藏字段,以防止跨站点请求伪造。 `templates/form/violations.html.twig` ```php {% extends 'base.html.twig' %} {% block title %}Violations{% endblock %} {% block body %} <h2>Validation failed</h2> <ul> {% for field, errorMessage in errorMessages %} <li>{{ field }}: {{ errorMessage }}</li> {% endfor %} </ul> {% endblock %} ``` 在违规视图中,我们浏览违规并列出它们。 ```php {% for field, errorMessage in errorMessages %} <li>{{ field }}: {{ errorMessage }}</li> {% endfor %} ``` 使用`for`指令,我们遍历错误消息并显示错误消息。 `templates/base.html.twig` ```php <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>{% block title %}Welcome!{% endblock %}</title> {% block stylesheets %}{% endblock %} </head> <body> {% block body %}{% endblock %} {% block javascripts %}{% endblock %} </body> </html> ``` 这是基本的 Twig 模板。 ```php $ php bin/console server:run ``` 我们启动开发服务器。 然后找到`localhost:8000/home`网址以获取表格。 在本教程中,我们验证了 Symfony 应用中的简单表单。 我们使用了手动验证。 您可能也对以下相关教程感兴趣: [Symfony 简介](/symfony/intro/), [Symfony DBAL 教程](/symfony/dbal/), [Symfony 表单教程](/symfony/form/), [PHP 教程](/lang/php/), 或列出[所有 Symfony 教程](/all/#symfony)。 {% endraw %}