>  기사  >  백엔드 개발  >  Symfony 데이터 검증 방법 분석

Symfony 데이터 검증 방법 분석

不言
不言원래의
2018-03-29 16:53:011390검색

이 기사는 Symfony 데이터 검증 방법을 예시로 분석합니다. 관심 있는 친구들이 한 번 살펴볼 수 있습니다.


검증은 웹 애플리케이션에서 일반적인 작업입니다. 양식에 입력된 데이터의 유효성을 검사해야 합니다. 또한 데이터를 데이터베이스에 기록하기 전이나 웹 서비스에 전달하기 전에 데이터를 확인해야 합니다.

Symfony2에는 검증 작업을 간단하고 이해하기 쉽게 만드는 Validator 구성 요소가 탑재되어 있습니다. 이 구성 요소는 JSR303 Bean 유효성 검사 사양을 기반으로 합니다. PHP에서 사용하기 위한 Java 사양입니다.

기본 검증

검증을 이해하는 가장 좋은 방법은 검증이 어떻게 수행되는지 확인하는 것입니다. 먼저, 애플리케이션 어딘가에서 사용되는 PHP 객체를 생성했다고 가정합니다.

코드는 다음과 같습니다:

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


지금까지는 애플리케이션의 특정 목적을 수행하는 일반적인 클래스에 불과합니다. 검증의 목적은 객체의 데이터가 합법적인지 여부를 알려주는 것입니다. 이를 위해서는 규칙이나 제약 조건 목록을 따르도록 개체를 구성하여 해당 데이터를 합법적으로 만들어야 합니다. 이러한 규칙은 다양한 형식(예: YAML, XML, 클래스 선언 또는 PHP)으로 설명될 수 있습니다. 예를 들어 $name 속성은 비어 있을 수 없으므로 다음 규칙을 추가합니다.

YAML 형식:

코드는 다음과 같습니다.

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


클래스 선언 형식:

코드는 다음과 같습니다. :

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

XML 형식:

코드는 다음과 같습니다.

<?xml version="1.0" encoding="UTF-8" ?>
<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping http://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">

PHP 코드 형식:

코드는 다음과 같습니다.

// 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(&#39;name&#39;, new NotBlank());
}
}

보호된 속성과 비공개 속성 및 getter 메서드도 확인할 수 있습니다.

검증기 서비스 사용:

다음으로 검증기 서비스의 검증 메서드를 사용하여 Author 개체를 실제로 검증합니다. 유효성 검사기의 작업은 간단합니다. 클래스의 제약 조건 규칙을 읽어 개체의 데이터가 이러한 규칙 제약 조건을 준수하는지 확인합니다. 유효성 검사에 실패하면 오류 배열이 반환됩니다. 이제 컨트롤러에서 이를 실행합니다.

코드는 다음과 같습니다.

use Symfony\Component\HttpFoundation\Response;
use Acme\BlogBundle\Entity\Author;
//...
public function indexAction()
{
$author = new Author();
//... 对$auother对象做些什么

$validator = $this->get(&#39;validator&#39;);
$errors = $validator->validate($author);
if(count($errors) >0){
return new Response(print_r($errors, true));
}else{
return new Response(&#39;The author is valid! Yes!&#39;);
}
}


$name 속성이 비어 있으면 다음 오류 메시지가 표시됩니다.

AcmeBlogBundleAuthor.name:
이 값은 be 공백

$name 속성에 값을 삽입하면 행복한 성공 메시지가 표시됩니다.

대부분의 경우 유효성 검사 서비스와 직접 통신할 필요가 없으며 인쇄 오류에 대해 전혀 걱정할 필요가 없습니다.

대부분의 경우 제출된 양식 데이터를 처리할 때 유효성 검사를 간접적으로 사용하게 됩니다.

오류 메시지 세트를 템플릿에 전달할 수도 있습니다.

코드는 다음과 같습니다.

if(count($errors)>0){
return $this->render(&#39;AcmeBlogBundle:Author:validate.html.twig&#39;,array(
&#39;errors&#39; => $errors,
));
}else{
//...
}


템플릿에서 필요에 따라 정확하게 오류 목록을 출력할 수 있습니다.

Twig 형식:

코드는 다음과 같습니다.

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

Checksum form

validator 서비스를 사용하면 언제든지 모든 개체의 유효성을 검사할 수 있습니다. 실제로 양식을 처리할 때 유효성 검사기를 간접적으로 사용하는 경우가 많습니다. Symfony의 양식 라이브러리는 유효성 검사기 서비스를 간접적으로 사용하여 데이터가 제출되고 바인딩된 후 기본 개체의 유효성을 검사합니다. 개체 제약 조건 위반 정보는 FieldError 개체로 변환되어 양식에 쉽게 표시될 수 있습니다. 컨트롤러의 전통적인 양식 제출 프로세스는 다음과 같습니다.

코드는 다음과 같습니다.

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() ==&#39;POST&#39;){
$form->bindRequest($request);

if($form->isvalid()){
//对$author做一些操作
return $this->redirect($this->generateUrl(&#39;...&#39;));
}
}
return $this->render(&#39;BlogBundle:Author:form.html.twig&#39;,array(
&#39;form&#39; => $form->createView(),
));
}

구성:

Symfony2의 유효성 검사기는 기본적으로 사용할 수 있습니다. 그러나 제약 조건을 지정하기 위해 life 메소드를 사용하는 경우 선언 기능을 명시적으로 활성화해야 합니다.

YAML 형식:

코드는 다음과 같습니다.

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

XML 형식:

코드는 다음과 같습니다. :





PHP 코드 형식:

코드는 다음과 같습니다.

// app/config/config.php
$contianer->loadFromExtension(&#39;framework&#39;,array(&#39;validation&#39;=> array(
&#39;enable_annotations&#39;=>true,
)));

제약 규칙

Validator는 제약 규칙에 따라 객체를 검증하도록 설계되었습니다. 개체의 유효성을 검사하려면 하나 이상의 제약 조건을 개체가 유효성을 검사하는 클래스에 매핑하고 유효성 검사기 서비스에 전달하면 됩니다.

기본적으로 제약 조건은 결정 문을 생성하는 간단한 PHP 개체입니다. 실제 생활에서 제약 조건은 "케이크는 태울 수 없습니다"와 같은 규칙 제약 조건일 수 있습니다. Symfony2에서는 제약 조건이 모두 동일합니다. 즉, 특정 조건이 참인지 여부를 결정합니다. 값이 주어지면 제약 조건은 해당 값이 제약 조건 규칙을 준수하는지 여부를 알려줍니다.

Symfony2에서 지원하는 제약 규칙

첫 번째는 기본 제약 규칙입니다. 이를 사용하여 객체의 속성 값이나 메서드의 반환 값과 같은 매우 기본적인 사항을 결정합니다.

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

문자열 제약 조건: Email, MinLength, MaxLength, Url, Regex, Ip 등
숫자 제약 조건: Max, Min
날짜 제약 조건: 날짜, 날짜/시간 및 시간

 수집 제약 조건: 선택, 컬렉션, UniqueEntity, 언어, 로케일 및 국가 등
 파일 제약 조건: 파일, 이미지
 기타 제약 조건: 콜백, 모두, 유효

사용자 정의 제약 조건을 만들 수도 있습니다.

제약 조건 구성:

NotBlank와 같은 일부 제약 조건은 매우 간단하지만 Choice 제약 조건과 같은 다른 제약 조건에는 설정해야 하는 구성 항목이 많습니다. Author 클래스에 다른 속성이 있다고 가정하면, gener는 "male" 또는 "female"로 설정될 수 있습니다:

YAML 형식:

코드는 다음과 같습니다:

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


클래스 선언 형식:

코드는 다음과 같습니다.

// 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;
}


XML 형식:

코드는 다음과 같습니다.

<?xml version="1.0" encoding="UTF-8" ?>
<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping http://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">

PHP 코드 형식:

코드는 다음과 같습니다.

// 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(&#39;gender&#39;, new Choice(array(
&#39;choices&#39; => array(&#39;male&#39;, &#39;female&#39;),
&#39;message&#39; => &#39;Choose a valid gender.&#39;,
)));
}
}

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

YAML格式:

代码如下:

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

类声明格式:

代码如下:

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

XML格式:

代码如下:

<?xml version="1.0" encoding="UTF-8" ?>
<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping http://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
male
female

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(&#39;gender&#39;, new Choice(array(&#39;male&#39;, &#39;female&#39;)));
}
}


约束目标

约束可以被用于一个类的属性或者一个公共的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


类声明格式:

代码如下:

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


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(&#39;firstName&#39;, new NotBlank());
$metadata->addPropertyConstraint(&#39;firstName&#39;, new MinLength(3));
}
}

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" }

类声明格式:

代码如下:

// 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
}
}


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(&#39;passwordLegal&#39;, new True(array(
&#39;message&#39; => &#39;The password cannot match your first name&#39;,
)));
}
}

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

代码如下:

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

眼尖的人可能会注意到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


类声明格式:

代码如下:

// 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;
}

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(&#39;email&#39;, new Email(array(
&#39;groups&#39; => array(&#39;registration&#39;)
)));
$metadata->addPropertyConstraint(&#39;password&#39;, new NotBlank(array(
&#39;groups&#39; => array(&#39;registration&#39;)
)));
$metadata->addPropertyConstraint(&#39;password&#39;, new MinLength(array(
&#39;limit&#39; => 7,
&#39;groups&#39; => array(&#39;registration&#39;)
)));
$metadata->addPropertyConstraint(&#39;city&#39;, new MinLength(3));
}
}

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

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

代码如下:

$errors = $validator->validate($author,array(&#39;registration&#39;));

值和数组校验

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

代码如下:

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


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

总结:

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

相关推荐:

Symfony查询方法小结分享

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

详解Symfony2框架表单的用法

위 내용은 Symfony 데이터 검증 방법 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.