{% raw %}

Symfony 验证教程

原文: 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 具有许多内置约束,包括NotBlankEmailLengthIsbn。 也可以创建自定义约束。

Symfony 验证示例

在示例中,我们有一个简单的表单,其中包含两个字段:nameemail。 提交表单后,我们使用 Symfony 的Validator手动验证字段。 在示例中,我们使用LengthNotBlankEmail约束。

安装组件

  1. $ composer create-project symfony/skeleton myval
  2. $ cd myval

我们创建一个新的 Symfony 项目,然后转到项目目录。

  1. $ composer req maker server --dev

我们安装symfony/maker-bundlesymfony/web-server-bundle。 这些对于开发模式很有用。 请注意,我们正在使用包的别名。

  1. $ composer req twig annotations

我们安装twig-bundle和注解。 注解位于sensio/framework-extra-bundle中。

  1. $ composer req validator

symfony/validator包包含 Symfony 验证工具。

  1. $ composer req security-csrf
  2. $ composer req monolog
  3. $ composer req property-access

跨站点请求伪造需要symfony/security-csrf包,symfony/monolog-bundle用于记录日志,symfony/property-access用于操纵 PHP 属性。

构建 Symfony 应用

  1. $ php bin/console make:controller HomeController

我们创建一个HomeController

src/Controller/HomeController.php

  1. <?php
  2. namespace App\Controller;
  3. use Symfony\Component\HttpFoundation\Response;
  4. use Symfony\Component\Routing\Annotation\Route;
  5. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  6. class HomeController extends AbstractController
  7. {
  8. /**
  9. * @Route("/home", name="home")
  10. */
  11. public function index(): Response
  12. {
  13. return $this->render('home/index.html.twig');
  14. }
  15. }

这是一个简单的控制器,可将包含 Web 表单的视图发送给用户。

  1. $ php bin/console make:controller FormController

我们创建一个FormController来响应表单提交。

src/Controller/FormController.php

  1. <?php
  2. namespace App\Controller;
  3. use Psr\Log\LoggerInterface;
  4. use Symfony\Component\HttpFoundation\Request;
  5. use Symfony\Component\HttpFoundation\Response;
  6. use Symfony\Component\Routing\Annotation\Route;
  7. use Symfony\Component\PropertyAccess\PropertyAccess;
  8. use Symfony\Component\Validator\Constraints as Assert;
  9. use Symfony\Component\Validator\Validator\ValidatorInterface;
  10. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  11. class FormController extends AbstractController
  12. {
  13. /**
  14. * @Route("/sendForm", name="form")
  15. */
  16. public function index(Request $request, ValidatorInterface $validator,
  17. LoggerInterface $logger): Response {
  18. $token = $request->request->get("token");
  19. if (!$this->isCsrfTokenValid('myform', $token)) {
  20. $logger->info("CSRF failure");
  21. return new Response("Operation not allowed", Response::HTTP_OK,
  22. ['content-type' => 'text/plain']);
  23. }
  24. $name = $request->request->get("name");
  25. $email = $request->request->get("email");
  26. $input = ['name' => $name, 'email' => $email];
  27. $constraints = new Assert\Collection([
  28. 'name' => [new Assert\Length(['min' => 2]), new Assert\NotBlank],
  29. 'email' => [new Assert\Email(), new Assert\notBlank],
  30. ]);
  31. $violations = $validator->validate($input, $constraints);
  32. if (count($violations) > 0) {
  33. $accessor = PropertyAccess::createPropertyAccessor();
  34. $errorMessages = [];
  35. foreach ($violations as $violation) {
  36. $accessor->setValue($errorMessages,
  37. $violation->getPropertyPath(),
  38. $violation->getMessage());
  39. }
  40. return $this->render('form/violations.html.twig',
  41. ['errorMessages' => $errorMessages]);
  42. } else {
  43. return new Response("Validation passed", Response::HTTP_OK,
  44. ['content-type' => 'text/plain']);
  45. }
  46. }
  47. }

FormController中,我们检查 CSRF 令牌,验证表单输入值,并将响应发送回客户端。

注意:为简单起见,我们将验证代码放入控制器中。 在生产应用中,最好将此类代码放在单独的服务类中。

  1. public function index(Request $request, ValidatorInterface $validator,
  2. LoggerInterface $logger)
  3. {

我们注入了请求对象,验证器对象和记录器对象。

  1. $token = $request->request->get("token");
  2. if (!$this->isCsrfTokenValid('myform', $token)) {
  3. $logger->info("CSRF failure");
  4. return new Response("Operation not allowed", Response::HTTP_OK,
  5. ['content-type' => 'text/plain']);
  6. }

我们检索令牌并使用isCsrfTokenValid()方法对其进行验证。

  1. $name = $request->request->get("name");
  2. $email = $request->request->get("email");
  3. $input = ['name' => $name, 'email' => $email];

我们获取请求输入参数,并将其放入数组中。

  1. $constraints = new Assert\Collection([
  2. 'name' => [new Assert\Length(['min' => 2]), new Assert\NotBlank],
  3. 'email' => [new Assert\Email(), new Assert\notBlank]
  4. ]);

我们创建约束的集合。 我们可以为单个值分配多个约束。

  1. $violations = $validator->validate($input, $constraints);

我们使用validate()方法对照约束条件验证输入数据。 该方法返回可能的违规。 Symfony 验证器返回ConstraintViolationList。 我们使用 Symfony 访问器来处理列表。

  1. if (count($violations) > 0) {

我们检查是否有违规行为。

  1. $accessor = PropertyAccess::createPropertyAccessor();
  2. $errorMessages = [];
  3. foreach ($violations as $violation) {
  4. $accessor->setValue($errorMessages,
  5. $violation->getPropertyPath(),
  6. $violation->getMessage());
  7. }

Symfony PropertyAccess用于在将违规消息发送到模板之前对其进行处理。 ConstraintViolationList转换为 PHP 数组,其中的键是表单字段,值是错误消息。 稍后使用for指令在 Twig 中处理该数组。

  1. return $this->render('form/violations.html.twig',
  2. ['errorMessages' => $errorMessages]);

我们在单独的页面中呈现错误消息。 这通常是使用 Flash 消息完成的。 看看 Symfony 保持表单值教程如何使用 Flash。

  1. } else {
  2. return new Response("Validation passed", Response::HTTP_OK,
  3. ['content-type' => 'text/plain']);
  4. }

如果一切正常,我们将发送一条简单消息验证已通过。

templates/home/index.html.twig

  1. {% extends 'base.html.twig' %}
  2. {% block title %}Home page{% endblock %}
  3. {% block body %}
  4. <form action="sendForm" method="post">
  5. <input type="hidden" name="token" value="{{ csrf_token('myform') }}" />
  6. <div>
  7. <label>Name:</label>
  8. <input type="text" name="name">
  9. </div>
  10. <div>
  11. <label>Email</label>
  12. <input type="email" name="email">
  13. </div>
  14. <button type="submit">Send</button>
  15. </form>
  16. {% endblock %}

该表格包含两个字段:姓名和电子邮件。

  1. <input type="hidden" name="token" value="{{ csrf_token('myform') }}" />

它还包含一个隐藏字段,以防止跨站点请求伪造。

templates/form/violations.html.twig

  1. {% extends 'base.html.twig' %}
  2. {% block title %}Violations{% endblock %}
  3. {% block body %}
  4. <h2>Validation failed</h2>
  5. <ul>
  6. {% for field, errorMessage in errorMessages %}
  7. <li>{{ field }}: {{ errorMessage }}</li>
  8. {% endfor %}
  9. </ul>
  10. {% endblock %}

在违规视图中,我们浏览违规并列出它们。

  1. {% for field, errorMessage in errorMessages %}
  2. <li>{{ field }}: {{ errorMessage }}</li>
  3. {% endfor %}

使用for指令,我们遍历错误消息并显示错误消息。

templates/base.html.twig

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>{% block title %}Welcome!{% endblock %}</title>
  6. {% block stylesheets %}{% endblock %}
  7. </head>
  8. <body>
  9. {% block body %}{% endblock %}
  10. {% block javascripts %}{% endblock %}
  11. </body>
  12. </html>

这是基本的 Twig 模板。

  1. $ php bin/console server:run

我们启动开发服务器。 然后找到localhost:8000/home网址以获取表格。

在本教程中,我们验证了 Symfony 应用中的简单表单。 我们使用了手动验证。

您可能也对以下相关教程感兴趣: Symfony 简介Symfony DBAL 教程Symfony 表单教程PHP 教程, 或列出所有 Symfony 教程

{% endraw %}