验证是Web应用程序中非常常见的任务。填入表单的数据需要验证,在它们被写入数据库或被发送给Web服务时也需要验证。
Symfony2附带的Validator组件使这个任务变得简单和透明。该组件基于JSR303 Bean验证规范。什么?在PHP中使用JAVA规范?你没听错,但它并不象听上去那么糟。让我们看看它是怎么在PHP使用的。
验证基础
最好的理解验证的方式就是在实战中学习。开始先假设你已经创建了一个简单PHP对象(plain-old-PHP-Object,简称POPO),你需要它在你应用程序中使用:
- // Acme/BlogBundle/Author.php
- class Author
- {
- public $name;
- }
目前为止,这还只是个普通的类,它在你的应用程序中实现一些目标。验证的目的就是要告诉你对象中的数据是否合法。为了能够进行验证,你需要配置一个对象必须遵循的规则列表(称为限制)。这些规则可以通过不同的格式(YAML、XML、注释或PHP)来指定。为了保证$name属性非空,必须添加下列内容:
- # Acme/BlogBundle/Resources/config/validation.yml
- Acme\BlogBundle\Author:
- properties:
- name:
- - NotBlank: ~
象“getter“一样,保护和私有属性也可以被验证(参见validator-constraint-targets)
使用验证服务
要验证Author对象,需要使用验证服务(Validator类)的validate方法。验证工作的容易的:查看类限制(如规则)并验证对象数据是否符合那些限制。如果验证失败,则返回一个错误数组。下面的来自控制器内部的简单示例:
- use Symfony\Component\HttpFoundation\Response;
- // ...
- public function indexAction()
- {
- $author = new Acme\BlogBundle\Author();
- // ... do something to the $author object
- $validator = $container->get('validator');
- $errorList = $validator->validate($author);
- if (count($errorList) > 0) {
- return new Response(print_r($errorList, true));
- } else {
- return new Response('The author is valid! Yes!');
- }
- }
如果$name属性为空,你将看到如下错误信息:
- Acme\BlogBundle\Author.name:
- This value should not be blank
如果你在name属性中插入值,那么得会出现验证成功的消息。
每个验证错误(称为“违反限制“),是由ConstraintViolation对象表现,该对象保持着一个描述错误的消息。此外validate方法返回一个类数组的ConstraintVoilationList对象。你还有很长的路要走,你可以用更先进的方式来使用验证并返回的错误。你可以先着色一个模板并将$errorList变量发送其中:
- if (count($errorList) > 0) {
- return $this->render('AcmeBlogBundle:Author:validate.html.twig', array(
- 'errorList' => $errorList,
- ));
- } else {
- // ...
- }
在模板中,你可以只输出你所需要的错误列表:
- {# src/Acme/BlogBundle/Resources/views/Author/validate.html.twig #}
- <h3>The author has the following errors</h3>
- <ul>
- {% for error in errorList %}
- <li>{{ error.message }}</li>
- {% endfor %}
- </ul>
验证和表单
无论何时,验证服务都可以用于验证任何对象。然而,实际上,你通常会通过Form类间接地使用验证。Form类使用验证服务在值被提交或约束时去验证底层对象。对象的限制约束被转换成FieldError对象,然后显示在你的表单中:
- $author = new Acme\BlogBundle\Author();
- $form = new Acme\BlogBundle\AuthorForm('author', $author, $this->get('validator'));
- $form->bind($this->get('request')->request->get('customer'));
- if ($form->isValid()) {
- // process the Author object
- } else {
- // render the template with the errors
- $this->render('BlogBundle:Author:form.html.twig', array('form' => $form));
- }
详情请参见表单章节。
配置
要使用Symfony2验证,需要确定它在你的应用程序配置中是可用的。
- # hello/config/config.yml
- framework:
- validation: { enabled: true, annotations: true }
如果你是通过注释映射限制的话,那么只需要将注释配置设置成true。
限制
验证是被设计用来验证对象是否违反限制(如规则)。要验证一个对象,只需简单地映射一个或多个限制到它的类,然后将其发送给验证服务。
限制简单地说是一个PHP对象,它生成一个限制规则的声明。在现实生活中,限制可以是“蛋糕不能燃烧”。在Symfony2中,限制也是相似的:它们被声明条件为真。指定一个值,限制将告诉你该值是否符合限制的规则。
限制支持
Symfony2包括了大量的常规限制。有关限制细节的完整列表可以在限制参考一节中找到。
配置限制
一些限制,如非空,是简单的。而其它的,如选择限制,则拥有几个可用的配置选项。这些可用选项在限制中是公共属性。通过发送一个选项数组给限制,它们中的每一个都可以被设置。假设Author类有另一个性别属性,该属性可以被设置成“男”或“女”:
- # Acme/BlogBundle/Resources/config/validation.yml
- Acme\BlogBundle\Author:
- properties:
- gender:
- - Choice: { choices: [male, female], message: Choose a valid gender. }
限制选项经常被作为数组发送。一些限制也允许你发送“缺省“选项到限制,以代替数组。在下面Choice限制的例子中,choices选项就是通过这一方式指定的:
- # Acme/BlogBundle/Resources/config/validation.yml
- Acme\BlogBundle\Author:
- properties:
- gender:
- - Choice: [male, female]
确保不要让指定选项的两个不同方法搞乱你。如果你不确定,检查限制的API文档或者总是发送选项数组(如上面第1种方法显示的那样),至少它是安全的。
限制的对象
限制可以被应用于一个类属性或一个公共的getter方法(如getFullName)。
属性
验证类属性是最基础的验证技巧。Symfony2允许你验证私有、保护和公共的属性。下面将向你展示如何配置Author类的$firstName和$lastName属性至少3个字符。
- # Acme/BlogBundle/Resources/config/validation.yml
- Acme\BlogBundle\Author:
- properties:
- firstName:
- - NotBlank: ~
- - MinLength: 3
- lastName:
- - NotBlank: ~
- - MinLength: 3
Getters
限制也可以应用在返回值的方法上。Symfony2允许你添加限制到任何名字中有着"get"或"is"的公共方法中。在本向导中,这两种类型的方法都被称为"getters“.
这种技巧的好处在于它允许你动态地验证你的对象。根据你对象的状态,方法返回不同值,然后验证。
下面将向你展示如何使用True限制去验证动态生成的令牌是否正确:
- # Acme/BlogBundle/Resources/config/validation.yml
- Acme\BlogBundle\Author:
- getters:
- tokenValid:
- - True: { message: "The token is invalid" }
公共的isTokenValid方法将执行一些逻辑去决定内部令牌是否合法,并返回true或false。
眼尖的你已经注意到getter的前缀("get"或"is")在映射中被忽略。这允许你将限制移到一个有着相同名字的属性(反之亦然),而无需改变你的验证逻辑。
最后一点
Symfony2验证器是一个强大的工具,它可以用来保证任何对象数据的“有效性”。验证背后的力量是“限制“,这是规则,你可以将其应用在属性或你对象的getter方法上。而你使用最常用的验证框架来间接地使用表单时,请记住,它可以在任何地方去验证任何对象。
本文转自 firehare 51CTO博客,原文链接:http://blog.51cto.com/firehare/581910,如需转载请自行联系原作者