{% raw %}
Symfony 验证教程
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约束。
安装组件
$ composer create-project symfony/skeleton myval$ cd myval
我们创建一个新的 Symfony 项目,然后转到项目目录。
$ composer req maker server --dev
我们安装symfony/maker-bundle和symfony/web-server-bundle。 这些对于开发模式很有用。 请注意,我们正在使用包的别名。
$ composer req twig annotations
我们安装twig-bundle和注解。 注解位于sensio/framework-extra-bundle中。
$ composer req validator
symfony/validator包包含 Symfony 验证工具。
$ composer req security-csrf$ composer req monolog$ composer req property-access
跨站点请求伪造需要symfony/security-csrf包,symfony/monolog-bundle用于记录日志,symfony/property-access用于操纵 PHP 属性。
构建 Symfony 应用
$ php bin/console make:controller HomeController
我们创建一个HomeController。
src/Controller/HomeController.php
<?phpnamespace 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 bin/console make:controller FormController
我们创建一个FormController来响应表单提交。
src/Controller/FormController.php
<?phpnamespace 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 令牌,验证表单输入值,并将响应发送回客户端。
注意:为简单起见,我们将验证代码放入控制器中。 在生产应用中,最好将此类代码放在单独的服务类中。
public function index(Request $request, ValidatorInterface $validator,LoggerInterface $logger){
我们注入了请求对象,验证器对象和记录器对象。
$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()方法对其进行验证。
$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);
我们使用validate()方法对照约束条件验证输入数据。 该方法返回可能的违规。 Symfony 验证器返回ConstraintViolationList。 我们使用 Symfony 访问器来处理列表。
if (count($violations) > 0) {
我们检查是否有违规行为。
$accessor = PropertyAccess::createPropertyAccessor();$errorMessages = [];foreach ($violations as $violation) {$accessor->setValue($errorMessages,$violation->getPropertyPath(),$violation->getMessage());}
Symfony PropertyAccess用于在将违规消息发送到模板之前对其进行处理。 ConstraintViolationList转换为 PHP 数组,其中的键是表单字段,值是错误消息。 稍后使用for指令在 Twig 中处理该数组。
return $this->render('form/violations.html.twig',['errorMessages' => $errorMessages]);
我们在单独的页面中呈现错误消息。 这通常是使用 Flash 消息完成的。 看看 Symfony 保持表单值教程如何使用 Flash。
} else {return new Response("Validation passed", Response::HTTP_OK,['content-type' => 'text/plain']);}
如果一切正常,我们将发送一条简单消息验证已通过。
templates/home/index.html.twig
{% 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 %}
该表格包含两个字段:姓名和电子邮件。
<input type="hidden" name="token" value="{{ csrf_token('myform') }}" />
它还包含一个隐藏字段,以防止跨站点请求伪造。
templates/form/violations.html.twig
{% 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 %}
在违规视图中,我们浏览违规并列出它们。
{% for field, errorMessage in errorMessages %}<li>{{ field }}: {{ errorMessage }}</li>{% endfor %}
使用for指令,我们遍历错误消息并显示错误消息。
templates/base.html.twig
<!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 bin/console server:run
我们启动开发服务器。 然后找到localhost:8000/home网址以获取表格。
在本教程中,我们验证了 Symfony 应用中的简单表单。 我们使用了手动验证。
您可能也对以下相关教程感兴趣: Symfony 简介, Symfony DBAL 教程, Symfony 表单教程, PHP 教程, 或列出所有 Symfony 教程。
{% endraw %}
