一、建立驗證器
- @Validator(name="ValidatorName") 宣告一個名字為 ValidatorName 的驗證器
- 驗證項是組成驗證器的唯一條件,標記有型別註解的屬性就是一個驗證項,一個驗證器可以有多個驗證項
驗證項
- 屬性的預設值就是引數的預設值,如果屬性沒有定義預設值,代表引數沒有定義預設值且必須傳遞。
- 一個屬性必須定義一個型別註解,否則不是一個驗證項且對引數驗證無效。
- 一個屬性可以多個條件註解,按照定義順序驗證資料。
- 預設屬性名稱就是需要驗證的引數名稱,也可以透過型別註解的 name 引數對映需要驗證的欄位名稱。
- 若驗證不透過時,將會丟擲 Swoft\Validator\Exception\ValidatorException 異常。
型別註解
@IsInt、@IsArray、@IsString、@IsFloat、@IsBool
引數 name 指定需要驗證欄位名字,message 指定驗證不透過時的錯誤資訊
條件註解
@AfterDate、@Alpha、@AlphaDash、@AlphaNum、@BeforeDate、@Chs、@ChsAlpha等比較多,在此無需一一羅列,參考官方文件即可
使用條件註解的時候一定要注意引用正確的驗證類
程式碼樣例
驗證器 TestValidator.php
<?php declare(strict_types=1);
namespace App\Validator;
use Swoft\Validator\Annotation\Mapping\AlphaDash;
use Swoft\Validator\Annotation\Mapping\Confirm;
use Swoft\Validator\Annotation\Mapping\IsString;
use Swoft\Validator\Annotation\Mapping\Length;
use Swoft\Validator\Annotation\Mapping\Validator;
/**
* Class TestValidator
* @Validator(name="TestValidator")
*/
class TestValidator
{
/**
* @IsString()
* @AlphaDash(message="名字必須是數字,字母,短橫,下劃線組合")
* @Length(min=4,max=20,message="名字長度在4~20之間")
* @var string
*/
protected $name;
/**
* @IsString()
* @AlphaDash(message="密碼必須是數字,字母,短橫,下劃線組合")
* @Length(min=6,max=15,message="密碼長度在6~15之間")
* @var string
*/
protected $password;
/**
* @IsString()
* @Confirm(name="password",message="確認密碼不一致")
* @var string
*/
protected $confirmPassword;
}
控制器類 TestController.php
<?php declare(strict_types=1);
namespace App\Http\Controller;
use Swoft\Context\Context;
use Swoft\Http\Message\ContentType;
use Swoft\Http\Message\Request;
use Swoft\Http\Message\Response;
use Swoft\Http\Server\Annotation\Mapping\Controller;
use Swoft\Http\Server\Annotation\Mapping\RequestMapping;
use Swoft\Http\Server\Annotation\Mapping\RequestMethod;
use Swoft\Validator\Annotation\Mapping\Validate;
/**
* Class TestController
* @package App\Http\Controller
* @Controller(prefix="test")
*/
class TestController
{
/**
* @RequestMapping(route="register",method={RequestMethod::POST})
* @Validate(validator="TestValidator")
* @param Request $request
* @return Response
*/
public function register(Request $request):Response
{
$name = $request->post('name');
$password = $request->post('password');
$age = $request->post('age');
$data = [
'name' => $name,
'age' => $age ?? 18,
'password' => $password,
];
$response = Context::mustGet()->getResponse();
$response = $response->withStatus(201)
->withContentType(ContentType::JSON)
->withData($data);
return $response;
}
}
在控制器中使用 @Validate 進行驗證
- validator 指定驗證器名稱
- fields 指定驗證器裡面驗證的欄位,這樣可以高效的重複使用驗證器
- type 預設 body,ValidateType::GET 驗證 GET 請求 query 引數
- params 自定義驗證器使用,傳遞給自定義驗證器的引數
二、自定義驗證規則
以定義一個正整數的驗證規則為例項進行講解
步驟一:宣告註解命令
<?php declare(strict_types=1);
namespace App\Annotation\Mapping;
use Doctrine\Common\Annotations\Annotation\Attribute;
use Doctrine\Common\Annotations\Annotation\Attributes;
/**
* Class PositiveInteger
* @package App\Annotation\Mapping
* @Annotation //宣告這個類是一個註解命令
* @Attributes({ //宣告註解引數集合
* @Attribute("message",type="string") //宣告註解具體的引數 name 引數的名字 type 引數值的型別
* })
*/
class PositiveInteger
{
/**
* @var string
*/
private $message = '';
/**
* PositiveInteger constructor.
* @param array $values
*/
public function __construct(array $values)
{
if( isset($values['value']) ){
$this->message = $values['value'];
}
if( isset($values['message']) ){
$this->message = $values['message'];
}
}
/**
* @return string
*/
public function getMessage(): string
{
return $this->message;
}
}
步驟二:宣告註解解析
註解命令要想能夠執行,則還需要定義一個註解命令的解析器,需要繼承
Swoft\Annotation\Annotation\Parser\Parser
類
<?php declare(strict_types=1);
use Swoft\Annotation\Annotation\Parser\Parser;
use Swoft\Annotation\Annotation\Mapping\AnnotationParser;
use Swoft\Validator\ValidatorRegister;
/**
* Class PositiveIntegerParser
* @AnnotationParser(annotation="PositiveInteger::class") //宣告要解析的註解命令
*/
class PositiveIntegerParser extends Parser{
/**
* @param int $type
* @param object $annotationObject
* @return array
* @throws ReflectionException
* @throws \Swoft\Validator\Exception\ValidatorException
*/
public function parse(int $type,$annotationObject):array
{
if($type !== self::TYPE_PROPERTY){
return [];
}
//向驗證器註冊一個驗證規則
ValidatorRegister::registerValidatorItem($this->className,
$this->propertyName,$annotationObject);
return [];
}
}
步驟三:宣告一個驗證規則
<?php declare(strict_types=1);
namespace App\Validator\Rule;
use Swoft\Bean\Annotation\Mapping\Bean;
use Swoft\Validator\Contract\RuleInterface;
use Swoft\Validator\Exception\ValidatorException;
/**
* Class PositiveIntegerRule
* @package App\Validator\Rule
* @Bean(PositiveInteger::class) //驗證器內部是透過 Bean 容器來獲得到我們的驗證規則的
*/
class PositiveIntegerRule implements RuleInterface
{
/**
* @param array $data 待驗證的所有資料
* @param string $propertyName 需要驗證的欄位名
* @param object $item 註解類的物件
* @param null $default 欄位的預設值
* @return array
* @throws ValidatorException
*/
public function validate(array $data, string $propertyName, $item, $default = null) :array
{
$message = $item->getMessage();
if( !isset($data[$propertyName]) && $default == null){
$message = empty($message) ? sprintf("s% 不能為空",$propertyName) : $message;
throw new ValidatorException($message,400);
}
if (is_numeric($data[$propertyName])
&& is_int($data[$propertyName] + 0)
&& ($data[$propertyName] + 0) > 0) {
return [$data];
}
$message = empty($message) ? sprintf("s% 必須是正整數",$propertyName) : $message;
throw new ValidatorException($message,400);
}
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結