Symfony data verification method analysis

不言
Release: 2023-03-22 17:28:01
Original
1335 people have browsed it

This article uses examples to analyze the Symfony data verification method. It is shared here for your reference. Interested friends can take a look at


Verification is a common task in web applications. Data entered into the form needs to be validated. Data also needs to be verified before being written to the database or when passed to a webservice.

Symfony2 is equipped with a Validator component, which makes the verification work simple and easy to understand. This component is based on the JSR303 Bean validation specification. A Java specification for use in PHP.

Basic Verification

The best way to understand verification is to see how it performs. First, assume that you have created a PHP object that is used somewhere in your application.

The code is as follows:

//src/Acme/BlogBundle/Entity/Author.php namespace Acme\BlogBundle\Entity; class Author { public $name; }
Copy after login


Up to now, it is just an ordinary class that serves some purpose of your application. The purpose of verification is to tell you whether the object's data is legal. For this purpose, you need to configure an object to follow a list of rules or constraints to make its data legal. These rules can be described in many different formats (e.g., YAML, XML, class declarations or PHP). For example, we ensure that the attribute $name cannot be empty, so add the following rules:

YAML format:

The code is as follows:

# src/Acme/BlogBundle/Resources/config/validation.yml Acme\BlogBundle\Entity\Author: properties: name: - NotBlank: ~
Copy after login


Class declaration Format:

The code is as follows:

// src/Acme/BlogBundle/Entity/Author.php use Symfony\Component\Validator\Constraints as Assert; class Author { /** * @Assert\NotBlank() */ public $name; }
Copy after login

XML format:

The code is as follows:

 
Copy after login
Copy after login

PHP code format:

The code is as follows:

// src/Acme/BlogBundle/Entity/Author.php use Symfony\Component\Validator\Mapping\ClassMetadata; use Symfony\Component\Validator\Constraints\NotBlank; class Author { public $name; public static function loadValidatorMetadata(ClassMetadata $metadata) { $metadata->addPropertyConstraint('name', new NotBlank()); } }
Copy after login

Protected and private attributes and getter methods can also be verified.

Use the validator service:

Next, use the validate method of the validator service to actually verify the Author object. The validator's job is simple: read the constraint rules of a class to verify whether the data of an object conforms to these rule constraints. If validation fails, an error array will be returned. Now we execute it in a controller:

The code is as follows:

use Symfony\Component\HttpFoundation\Response; use Acme\BlogBundle\Entity\Author; //... public function indexAction() { $author = new Author(); //... 对$auother对象做些什么 $validator = $this->get('validator'); $errors = $validator->validate($author); if(count($errors) >0){ return new Response(print_r($errors, true)); }else{ return new Response('The author is valid! Yes!'); } }
Copy after login


If the $name attribute is empty, you will see the following Error message:

Acme\BlogBundle\Author.name:
This value should not be blank

If you insert a value for the $name attribute, then you will have happy success information.

Most of the time, you don't need to communicate directly with the validator service or worry about printing errors at all.

In most cases, you will use validation indirectly when processing submitted form data.

You can also pass a collection of error messages to a template:

The code is as follows:

if(count($errors)>0){ return $this->render('AcmeBlogBundle:Author:validate.html.twig',array( 'errors' => $errors, )); }else{ //... }
Copy after login


In the template, You can output the error list as accurately as you need:

Twig format:

The code is as follows:

{# src/Acme/BlogBundle/Resources/views/Author/validate.html.twig #} The author has the following errros {% for error in errors %} {{ error.message }} {% endfor %}
Copy after login

Checksum form

## The #validator service can be used to validate any object at any time. In fact, you will often use validators indirectly when processing forms. Symfony's form library indirectly uses the validator service to validate the underlying objects after the data has been submitted and bound. Object constraint violation information will be converted to a FieldError object, which can be easily displayed in your form. The traditional form submission process in a controller is as follows:


The code is as follows:

use Acme\BlogBundle\Entity\Author; use Acme\BlogBundle\Form\AuthorType; use Acme\Component\HttpFoundation\Request; //... public function updateAction(Request $request) { $author = new Acme\BlogBundle\Entity\Author(); $form = $this->createForm(new AuthorType(),$author); if($request->getMethod() =='POST'){ $form->bindRequest($request); if($form->isvalid()){ //对$author做一些操作 return $this->redirect($this->generateUrl('...')); } } return $this->render('BlogBundle:Author:form.html.twig',array( 'form' => $form->createView(), )); }
Copy after login

Configuration:

The validator of Symfony2 is available by default. But if you use the life method to specify your constraints, then you need to explicitly enable the declaration function:

YAML format:


The code is as follows:

# app/config/config.yml framework: validation: {enable_annotations: true }
Copy after login

XML format:


The code is as follows:




##PHP code format:



The code is as follows:

// app/config/config.php $contianer->loadFromExtension('framework',array('validation'=> array( 'enable_annotations'=>true, )));
Copy after login

Constraint rules

Validator is designed to verify objects according to constraint rules. To validate an object, just map one or more constraints to the class it is validating and pass it to the validator service.

Essentially, a constraint is a simple PHP object that generates a decision statement. In real life, a constraint can be a rule constraint such as "the cake cannot be burned". In Symfony2, constraints are all the same: they determine whether a certain condition is true or not. Given a value, the constraint tells you whether the value obeys your constraint rules.

Constraint rules supported by Symfony2

The first is the basic constraint rules: use them to determine very basic things, such as the value of your object's property or the return value of a method.

NotBlank, Blank, NotNull, Null, True, False, Type

String constraints: Email, MinLength, MaxLength, Url, Regex, Ip, etc.

Numeric constraints: Max, Min

Date constraints: Date, DateTime and Time

Collection constraints: Choice, Collection, UniqueEntity, Language, Locale and Country, etc.

File constraints: File, Image

Other constraints: Callback, All, Valid


You can also create your own custom constraints.

Constraint configuration:

Some constraints, such as NotBlank, are very simple, but others, such as Choice constraints, have many configuration items that need to be set. Assuming that the Author class has another attribute, gener can be set to "male" or "female":

YAML format:


The code is as follows:

# src/Acme/BlogBundle/Resources/config/validation.yml Acme\BlogBundle\Entity\Author: properties: gener: - Choice: { choices: [male, female], message: Choos a valid gender. }
Copy after login

Class declaration format:



The code is as follows:

// src/Acme/BlogBundle/Entity/Author.php use Symfony\Component\Validator\Constraints as Assert; class Author { /** * @Assert\Choice( * choices = {"male","female"}, * message = "Choose a valid gender." * ) */ public $gender; }
Copy after login


XML format:


The code is as follows:

 
Copy after login
Copy after login

PHP code format:


The code is as follows:

// src/Acme/BlogBundle/Entity/Author.php use Symfony\Component\Validator\Mapping\ClassMetadata; use Symfony\Component\Validator\Constraints\NotBlank; class Author { public $gender; public static function loadValidatorMetadata(ClassMetadata $metadata) { $metadata->addPropertyConstraint('gender', new Choice(array( 'choices' => array('male', 'female'), 'message' => 'Choose a valid gender.', ))); } }
Copy after login

一个约束的选项通常都是通过一个数组来传递的。有些约束也允许你传递一个值。"default"在数组中是可选的。在Choice约束时,choices选项就可以通过这种方式指定。

YAML格式:

代码如下:

# src/Acme/BlogBundle/Resources/config/validation.yml Acme\BlogBundle\Entity\Author: properties: gender: - Choice: [male, female]
Copy after login

类声明格式:

代码如下:

// src/Acme/BlogBundle/Entity/Author.php use Symfony\Component\Validator\Constraints as Assert; class Author { /** * @Assert\Choice({"male", "female"}) */ protected $gender; }
Copy after login

XML格式:

代码如下:

  male female
Copy after login

PHP格式:

代码如下:

// src/Acme/BlogBundle/Entity/Author.php use Symfony\Component\Validator\Mapping\ClassMetadata; use Symfony\Component\Validator\Constraints\Choice; class Author { protected $gender; public static function loadValidatorMetadata(ClassMetadata $metadata) { $metadata->addPropertyConstraint('gender', new Choice(array('male', 'female'))); } }
Copy after login


约束目标

约束可以被用于一个类的属性或者一个公共的getter方法。属性约束最常用也最简单,而公共的getter方法约束则允许你指定一个复杂的约束规则。

属性约束:

校验类的属性石一个最常规的校验技术。Symfony2允许你校验private,protected或者public属性。下面代码显示如何配置Author对象的$firstName属性至少有3个字符:

YAML格式:

代码如下:

# src/Acme/BlogBundle/Resources/config/validation.yml Acme\BlogBundle\Entity\Author: properties: firstName: - NotBlank: ~ - MinLength: 3
Copy after login


类声明格式:

代码如下:

// Acme/BlogBundle/Entity/Author.php use Symfony\Component\Validator\Constraints as Assert; class Author { /** * @Assert\NotBlank() * @Assert\MinLength(3) */ private $firstName; }
Copy after login


XML格式:

代码如下:





3


PHP代码格式:

代码如下:

// src/Acme/BlogBundle/Entity/Author.php use Symfony\Component\Validator\Mapping\ClassMetadata; use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Constraints\MinLength; class Author { private $firstName; public static function loadValidatorMetadata(ClassMetadata $metadata) { $metadata->addPropertyConstraint('firstName', new NotBlank()); $metadata->addPropertyConstraint('firstName', new MinLength(3)); } }
Copy after login

Getters

约束也可以应用于一个方法的返回值。Symfony2 允许你添加一个约束到任何"get"或者 "is"开头的public方法。该技术的好处是允许你动态的校验你的对象。比如,假设你想确认密码字段不匹配用户的first name(因为安全原因)。你可以通过创建一个idPasswordLegal 方法,然后决断这个方法必须返回true:

YAML格式:

代码如下:

# src/Acme/BlogBundle/Resources/config/validation.yml Acme\BlogBundle\Entity\Author: getters: passwordLegal: - "True": { message: "The password cannot match your first name" }
Copy after login

类声明格式:

代码如下:

// src/Acme/BlogBundle/Entity/Author.php use Symfony\Component\Validator\Constraints as Assert; class Author { /** * @Assert\True(message = "The password cannot match your first name") */ public function isPasswordLegal() { // return true or false } }
Copy after login


XML格式:

代码如下:


PHP代码格式:

代码如下:

// src/Acme/BlogBundle/Entity/Author.php use Symfony\Component\Validator\Mapping\ClassMetadata; use Symfony\Component\Validator\Constraints\True; class Author { public static function loadValidatorMetadata(ClassMetadata $metadata) { $metadata->addGetterConstraint('passwordLegal', new True(array( 'message' => 'The password cannot match your first name', ))); } }
Copy after login

现在我们创建一个isPasswordLegal()方法,并且包含你需要逻辑:

代码如下:

public function isPasswordLegal() { return ($this->firstName != $this->password); }
Copy after login

眼尖的人可能会注意到getter的前缀("get"或者"is")在映射时被忽略了。这允许你在不改变校验规则的前提下,把一个约束移动到一个具有同名属性上,反之亦然。


类:

一些约束应用到整个类被校验上面。比如,Callback约束是一个通用约束,它可以应用到类自身。当类被校验时,被约束描述的方法只是被执行这样每一个可以提供更个性化的校验。

校验分组

到目前为止,你已经能够添加约束到类并询问是否该类传入所有定义的约束规则。一些情况下,你只需要使用该类的其中某些规则来校验一个对象。要做到这些,你可以组织每一个约束到一个或者多个校验组中,然后应用使用其中一组校验。比如,假设你有一个User类,它会在用户注册和用户更新他们的联系信息时使用。

YAML格式:

代码如下:

# src/Acme/BlogBundle/Resources/config/validation.yml Acme\BlogBundle\Entity\User: properties: email: - Email: { groups: [registration] } password: - NotBlank: { groups: [registration] } - MinLength: { limit: 7, groups: [registration] } city: - MinLength: 2
Copy after login


类声明格式:

代码如下:

// src/Acme/BlogBundle/Entity/User.php namespace Acme\BlogBundle\Entity; use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Validator\Constraints as Assert; class User implements UserInterface { /** * @Assert\Email(groups={"registration"}) */ private $email; /** * @Assert\NotBlank(groups={"registration"}) * @Assert\MinLength(limit=7, groups={"registration"}) */ private $password; /** * @Assert\MinLength(2) */ private $city; }
Copy after login

XML格式:

代码如下:

7

PHP代码格式:

代码如下:

// src/Acme/BlogBundle/Entity/User.php namespace Acme\BlogBundle\Entity; use Symfony\Component\Validator\Mapping\ClassMetadata; use Symfony\Component\Validator\Constraints\Email; use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Constraints\MinLength; class User { public static function loadValidatorMetadata(ClassMetadata $metadata) { $metadata->addPropertyConstraint('email', new Email(array( 'groups' => array('registration') ))); $metadata->addPropertyConstraint('password', new NotBlank(array( 'groups' => array('registration') ))); $metadata->addPropertyConstraint('password', new MinLength(array( 'limit' => 7, 'groups' => array('registration') ))); $metadata->addPropertyConstraint('city', new MinLength(3)); } }
Copy after login

这里我们配置了两个校验组:
default默认组: 包括所有没有分配到任何组的约束规则
registration: 只包含了email和password字段的校验规则

告诉validator使用指定的校验组,传一个或者多个组名作为validate()方法的第二个参数即可:

代码如下:

$errors = $validator->validate($author,array('registration'));
Copy after login

值和数组校验

到目前为止,我们已经看了如何校验整个对象。但是有时候,我们可能想值校验一个单独的值,比如校验一个字符串是不是一个合法的email地址。这非常简单,在Controller类中进行如下:

代码如下:

// 在controller类前引用相应的校验命名空间 use Symfony\Component\Validator\Constraints\Email; public function addEmailAction($email) { $emailConstraint = new Email(); // 所有的校验选项(options)都可以这样设置 $emailConstraint->message = 'Invalid email address'; // 使用validator来校验一个值 $errorList = $this->get('validator')->validateValue($email, $emailConstraint); if (count($errorList) == 0) { // 这是一个合法的email地址,可以做些什么 } else { // 这是一个非法的email地址 $errorMessage = $errorList[0]->getMessage() // 做一些错误处理 } // ... }
Copy after login


通过调用validator的validateValue方法,你可以传入一个原始值和一个你要使用的校验对象。该方法会返回一个ConstraintViolationList对象,它扮演的只是一个错误信息数组的角色。集合中的每一个错误是一个ConstraintViolation对象,使用对象的getMessage方法可以获取错误信息。

总结:

Symfony2 的validator是一个强大的工具,它可以被用来保证任何对象数据的合法性。它的强大来源于约束规则,你可以把它们应用于你对象的属性和getter方法。其实,你大多数情况下都是在使用表单时,间接的应用了校验框架,记住它可以被应用于任何地方校验任何对象。

相关推荐:

Symfony查询方法小结分享

Symfony2针对输入时间进行查询实例详解

详解Symfony2框架表单的用法

The above is the detailed content of Symfony data verification method analysis. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!