国产+高潮+在线,国产 av 仑乱内谢,www国产亚洲精品久久,51国产偷自视频区视频,成人午夜精品网站在线观看

分享一個(gè)多功能的驗(yàn)證器,可以對(duì)數(shù)據(jù)進(jìn)行轉(zhuǎn)換、驗(yàn)證、過濾

chaz6chez

這個(gè)項(xiàng)目由來很久了,大概至少有6年的歷史,最早我工作的時(shí)候接觸的一個(gè)項(xiàng)目叫struct,他可以把數(shù)組映射到對(duì)象屬性上進(jìn)行數(shù)據(jù)類型內(nèi)容等判斷或者過濾,也可以進(jìn)行轉(zhuǎn)換,也可以自行注冊(cè)handle進(jìn)行過濾、判斷;后來我把這個(gè)項(xiàng)目重構(gòu)了一下,適用在常駐內(nèi)存的環(huán)境下,同時(shí),這個(gè)項(xiàng)目也是我用在生產(chǎn)環(huán)境中的一個(gè)項(xiàng)目;

這個(gè)項(xiàng)目有點(diǎn)像殘疾的注解,不過我覺得用起來還挺好的,所以推薦給大家

測(cè)試覆蓋率應(yīng)該超過了80%,常用的幾種方案都是100%覆蓋的;

項(xiàng)目地址:https://github.com/chaz6chez/structure

1.x已經(jīng)沒有再維護(hù)了,現(xiàn)在只維護(hù)2.x

引入

composer require chaz6chez/structure

應(yīng)用場(chǎng)景

  • 出入?yún)⒌呐袛嗉斑^濾
  • 數(shù)據(jù)轉(zhuǎn)化及映射

示例

驗(yàn)證場(chǎng)景

  • 創(chuàng)建一個(gè)Structure
namespace YoursNamespace;
use Structure\Struct;
class User extends Struct {

    // 當(dāng)id為非null值時(shí),必須滿足int 10 < id < 20
    /**
     * @rule int,min:10,max:20|id format error:1001
     */
    public $id; 

    // name為必填,必須滿足string 1 < name長(zhǎng)度 < 20
    /**
     * @rule string,min:1,max:20|name format error:2001
     * @required true|name cannot be empty:2002 
     */
    public $name;

    // 當(dāng)sex為null時(shí)默認(rèn) string female
    // 滿足string 0 < sex長(zhǎng)度 < 10
    /**
     * @rule string,min:0,max:10|sex format error:1001
     * @default string:female
     */
    public $sex;
}
  • 使用
    $struct = \YoursNamespace\User::factory();
    $struct->create([
        'id' => 12,
        'name' => 'John Smith'
    ]);

    // or

    $struct = \YoursNamespace\User::factory([
        'id' => 12,
        'name' => 'John Smith'
    ]);

    // or

    $struct = new \YoursNamespace\User();
    $struct = \YoursNamespace\User::factory();

    $struct->id = 12;
    $struct->name = 'John Smith';

    // or

    $struct = new \YoursNamespace\User([
        'id' => 12,
        'name' => 'John Smith'
    ]);

    if($struct->hasError()) {
        throw new \RuntimeException(
            $struct->getError()->getMessage() . '->' . $struct->getError()->getPosition(),
            $struct->getError()->getCode()
        );
    }
    return $struct->output(); // array

使用說明

  • 繼承 Structure\Struct 及實(shí)現(xiàn)結(jié)構(gòu)體
  • public屬性接參
namespace Example;

use Structure\Struct;

class User extends Struct{
    public $id;
    public $name;
    public $sex;
}
  • 對(duì)要操作和轉(zhuǎn)化的public屬性進(jìn)行注釋

    /**
     * @rule string,min:10,max:20|name format error:1001 
     */
    public $name;
  • 標(biāo)簽分為四個(gè)區(qū)域
    • a區(qū):標(biāo)簽區(qū)
    • b區(qū):場(chǎng)景區(qū)
    • c區(qū):驗(yàn)證區(qū)
    • d區(qū):內(nèi)容信息
/**
 *  a區(qū)   b區(qū)        c區(qū)              d區(qū)
 * @標(biāo)簽 [場(chǎng)景]   驗(yàn)證方式   | 錯(cuò)誤信息     : 錯(cuò)誤碼
 *      ↓           ↓           ↓             ↓
 * @rule[check] string,min:1|error message:error code  
 */                       

標(biāo)簽區(qū):

  • 轉(zhuǎn)換類的標(biāo)簽配合 filter()在output() 方法內(nèi)生效,
    會(huì)對(duì)包含該標(biāo)簽的屬性執(zhí)行轉(zhuǎn)換或者過濾操作

  • 驗(yàn)證類的標(biāo)簽在 validate() 中生效返回布爾值,
    通過getError() 可以獲得錯(cuò)誤信息

標(biāo)簽名 方式 類型 說明
@default Structure\Handler、func、method 轉(zhuǎn)換 func與method是將返回值默認(rèn)賦予該標(biāo)簽
@required true 驗(yàn)證 判斷是否為必要值
@rule Structure\Handler、func、method 驗(yàn)證 以func與method的bool返回類型判斷驗(yàn)證
@skip 驗(yàn)證 跳過驗(yàn)證
@ghost 轉(zhuǎn)換 跳過輸出
@key 轉(zhuǎn)換 標(biāo)記鑰匙屬性
@mapping 映射鍵名 轉(zhuǎn)換 映射鍵轉(zhuǎn)換
@operator true、func、method 轉(zhuǎn)換 鍵值特殊轉(zhuǎn)換

@default

  • 將該屬性標(biāo)記默認(rèn)模式
  • 當(dāng)該屬性值為null且具備@default標(biāo)簽時(shí)生效
    /**
     * @default string:abc
     * @default int:123
     * @default float:1.1
     * @default object:Handler\Help
     * @default map:{"a":"1"}
     * @default array:["1"]
     * @default bool:true
     */
    public $name;
  • 驗(yàn)證區(qū)可使用func、method進(jìn)行方法賦值
    • method:className,methodName 必須是靜態(tài)方法
    • 方法執(zhí)行過程中拋出的任何異常都會(huì)被忽略,并以默認(rèn)Null賦值
    /**
     * @default func:is_array              會(huì)找到is_array函數(shù)
     * @default method:_set                會(huì)定位當(dāng)前類的_set方法
     * @default method:Handler\Help,get   會(huì)定位Handler\Help類的get方法 
     */
    public $name;
    public static function _set(){
        return 'abc';
    }
  • @default僅在output()輸出時(shí)生效,若要直接使用類屬性獲取@default賦值,請(qǐng)使用以下方法:
  • 但不建議頻繁使用,會(huì)多執(zhí)行一次object clone操作
    // 以name的@default標(biāo)簽為string:John舉例
    /**
     * @default string:John
     */
    public $name;
    $struct = new Struct();
    // @default無法生效,值為null
    $struct->name;
    // @default可以生效,值為字符串John
    $struct()->name;

@required

    /**
     * @required true|name cannot empty
     */
    public $name;

@rule

  • 通過預(yù)置Handler進(jìn)行驗(yàn)證
    /**
     * @rule string,min:10,max:20|name format error
     * @rule int,min:10,max:20|name format error
     * @rule float,min:1.0,max:2.1,scale:3|name format error
     * @rule bool,true|name format error
     * @rule object,class:|name format error
     * @rule array,min:10,max:20,values:string|name format error
     * @rule map,min:1,max:5,keys:string,values:int|name format error
     * @rule url,path:true,query:true|name format error
     * @rule ip,ipv4:false,ipv6:false,private:false,reserved:false|name format error
     * @rule regex,min:10,max:20,regex:/.?/|name format error
     */
    public $name;
  • 驗(yàn)證區(qū)可使用func、method進(jìn)行方法判斷
    • method:className,methodName 必須是靜態(tài)方法
    • 方法執(zhí)行過程中任何異常會(huì)轉(zhuǎn)化成StructureException拋出
    /**
     * @rule func:_set                  會(huì)找到_set函數(shù)
     * @rule method:_set                會(huì)定位當(dāng)前類的_set方法
     * @rule method:Handler\Help,get   會(huì)定位Handler\Help類的get方法
     */
    public $name;

    public static function _set($value) : bool
    {
        return $value === '_method';
    }
}

function _set($value) : bool
{
    return $value === '_func';
}

@ghost

  • output() 不會(huì)輸出該標(biāo)簽
    // @ghost true
    $user->id = 'id';

    $user->name = 'name';
    $user->output();
    // 以上會(huì)輸出
    [
        'name' => 'name'
    ];

    $user->output(true);
    // 以上會(huì)輸出
    [
        'id' => 'id',
        'name' => 'name'
    ];

@key

  • 將該屬性標(biāo)記鑰匙字段
  • 通過 filter()->output() 可以做到僅輸出鑰匙字段
    // @key true
    $user->id = 'id';

    $user->name = 'name';
    $user->filter(STRUCT_FILTER_KEY)->output();
    // 以上會(huì)輸出
    [
        'name' => 'name'
    ];

    $user->transfer(STRUCT_FILTER_KEY_REVERSE)->output();
    // 以上會(huì)輸出
    [
        'id' => 'id',
    ];

@skip

  • 跳過驗(yàn)證,但不影響輸出

@operator

1. 識(shí)別medoo語(yǔ)法-where 并轉(zhuǎn)換

    /**
     * @operator true 
     */ 
    public $name;

通過 transfer()->output() 可以做到轉(zhuǎn)換輸出

    // @operator true
    $user->id = 'abc[>]';
    $user->transfer(STRUCT_TRANSFER_OPERATOR)->output();
    // 以上會(huì)輸出
    [
        'id[>]' => 'abc'
    ];

    $user->id = '123,456[<>]';
    $user->transfer(STRUCT_TRANSFER_OPERATOR)->output();
    // 以上會(huì)輸出
    [
        'id[<>]' => ['123','456'],
    ];
2.2以上版本完善了該標(biāo)簽下的類型轉(zhuǎn)換
2.2以下版本中不會(huì)對(duì)類型轉(zhuǎn)換
2.2以下版本:
    // @operator true
    $user->id = '123[>]';
    $user->transfer(STRUCT_TRANSFER_OPERATOR)->output();
    // 以上會(huì)輸出
    [
        'id[>]' => '123'
    ];
    // 并非期待的
    [
       'id[>]' => 123
    ];
    // 此種狀況會(huì)影響數(shù)據(jù)庫(kù)查詢的索引
2.2以上版本:
  • 不僅可以配合medoo語(yǔ)法做處理轉(zhuǎn)換,也可以直接做類型轉(zhuǎn)換
  • 字符串類型的數(shù)字默認(rèn)會(huì)根據(jù)值類型轉(zhuǎn)換
    • 整型內(nèi)容字符串轉(zhuǎn)換成整型
    • 小數(shù)字符串轉(zhuǎn)換成浮點(diǎn)型
    // @operator true
    $user->id = '123[>]';
    $user->transfer(STRUCT_TRANSFER_OPERATOR)->output();
    // 以上會(huì)輸出 int
    [
        'id[>]' => 123
    ];

    // @operator true
    $user->id = '123';
    $user->transfer(STRUCT_TRANSFER_OPERATOR)->output();
    // 以上會(huì)輸出 int
    [
        'id' => 123
    ];

    $user->id = '1.23[>]';
    $user->transfer(STRUCT_TRANSFER_OPERATOR)->output();
    // 以上會(huì)輸出 float
    [
        'id[>]' => 1.23
    ];

    $user->id = '1.23';
    $user->transfer(STRUCT_TRANSFER_OPERATOR)->output();
    // 以上會(huì)輸出
    [
        'id' => 1.23
    ];
  • 可以使用強(qiáng)制轉(zhuǎn)換標(biāo)簽

# String :

    // @operator true
    $user->id = '123[String][>]';
    $user->transfer(STRUCT_TRANSFER_OPERATOR)->output();
    // 以上會(huì)輸出 int
    [
        'id[>]' => '123'
    ];

    // @operator true
    $user->id = '123[String]';
    $user->transfer(STRUCT_TRANSFER_OPERATOR)->output();
    // 以上會(huì)輸出 int
    [
        'id' => '123'
    ];

# Int :

    // @operator true
    $user->id = '1[Int][>]';
    $user->transfer(STRUCT_TRANSFER_OPERATOR)->output();
    // 以上會(huì)輸出 int
    [
        'id[>]' => 1
    ];

    // @operator true
    $user->id = '1[Int]';
    $user->transfer(STRUCT_TRANSFER_OPERATOR)->output();
    // 以上會(huì)輸出 int
    [
        'id' => 1
    ];

# Float :

    // @operator true
    $user->id = '123[Float][>]';
    $user->transfer(STRUCT_TRANSFER_OPERATOR)->output();
    // 以上會(huì)輸出 int
    [
        'id[>]' => 123.0
    ];

    // @operator true
    $user->id = '123[Float]';
    $user->transfer(STRUCT_TRANSFER_OPERATOR)->output();
    // 以上會(huì)輸出 int
    [
        'id' => 123.0
    ];

# Bool :

    // @operator true
    $user->id = '1[Bool][>]'; // 0 false
    $user->transfer(STRUCT_TRANSFER_OPERATOR)->output();
    // 以上會(huì)輸出 int
    [
        'id[>]' => true
    ];

    // @operator true
    $user->id = '1[Bool]'; // 0 false
    $user->transfer(STRUCT_TRANSFER_OPERATOR)->output();
    // 以上會(huì)輸出 int
    [
        'id' => true
    ];

2.使用func、method進(jìn)行轉(zhuǎn)換

  • method:className,methodName 必須是靜態(tài)方法
  • 方法執(zhí)行過程中任何異常會(huì)轉(zhuǎn)化成StructureException拋出

    /**
     * @operator func:_add                  相當(dāng)于_add($name)
     * @operator method:_add                相當(dāng)于$this->_add($name)
     * @operator method:Handler\Help,_add  相當(dāng)于Handler\Help::_add($name)
     */
    public $name;

@mapping

  • 將該屬性標(biāo)記映射處理
  • 通過 transfer()->output() 可以做到轉(zhuǎn)換輸出
    // @mapping key
    $user->id = 123;

    $user->name = 'john';
    $user->output();
    // 輸出
    [
        'id' => 123,
        'name' => 'john'
    ];

    $user->transfer(STRUCT_TRANSFER_MAPPING)->output();
    // 輸出
    [
        'key' => 123,
        'name' => 'john'
    ];

方法

  • 實(shí)例化
    $user = User::factory([
        'id' => 1,
        'name' => 'john'
    ],'check');
  • 輸入

    • 使用create方法輸入數(shù)據(jù)
    • 使用屬性賦值輸入數(shù)據(jù)
    • 使用create可以保存原始數(shù)據(jù),使用屬性賦值則不會(huì)保留原始數(shù)據(jù)
    // 1.使用create輸入數(shù)據(jù)
    $user->create([
        'id' => 1,
        'name' => 'john'
    ]); // return $this
    // 2.使用屬性賦值輸入數(shù)據(jù)
    $user->id = 1;
    $user->name = 'john';

    // 使用create可以保存原始數(shù)據(jù),建議使用create輸入數(shù)據(jù)
  • 獲取原始數(shù)據(jù)
    $user->getRaw(); // return array
  • 設(shè)置場(chǎng)景
    $user->scene('check'); // return $this
  • 轉(zhuǎn)換

    • STRUCT_TRANSFER_MAPPING
    • STRUCT_TRANSFER_OPERATOR
    $user->transfer(STRUCT_TRANSFER_MAPPING); // return $this

    // STRUCT_TRANSFER_MAPPING
    // STRUCT_TRANSFER_OPERATOR

    // 接受可變長(zhǎng)參數(shù)
    $user->transfer(
        STRUCT_TRANSFER_MAPPING,
        STRUCT_TRANSFER_OPERATOR
    ); // return $this
  • 過濾
    • STRUCT_FILTER_NULL
    • STRUCT_FILTER_EMPTY
    • STRUCT_FILTER_ZERO
    • STRUCT_FILTER_KEY
    • STRUCT_FILTER_KEY_REVERSE
    • STRUCT_FILTER_OPERATOR
    • STRUCT_FILTER_OPERATOR_REVERSE
    $user->filter(STRUCT_FILTER_NULL); // return $this

    // STRUCT_FILTER_NULL
    // STRUCT_FILTER_EMPTY
    // STRUCT_FILTER_ZERO
    // STRUCT_FILTER_KEY
    // STRUCT_FILTER_KEY_REVERSE
    // STRUCT_FILTER_OPERATOR
    // STRUCT_FILTER_OPERATOR_REVERSE

    // 接受可變長(zhǎng)參數(shù)
    $user->filter(
        STRUCT_FILTER_NULL,
        STRUCT_FILTER_EMPTY
    ); // return $this
  • 驗(yàn)證
    $user->validate(); // return bool
    $user->hasError(); // return bool

    // true 有錯(cuò)誤,驗(yàn)證未通過
    // false 無錯(cuò)誤,驗(yàn)證通過
  • 獲取錯(cuò)誤

    • 需要在驗(yàn)證執(zhí)行后才能獲取錯(cuò)誤信息
    $user->getError(); // return Structure\Error

    $user->getError()->getMessage();  // 錯(cuò)誤信息 string
    $user->getError()->getCode();     // 錯(cuò)誤碼 string
    $user->getError()->getField();    // 字段名 string
    $user->getError()->getPosition(); // 錯(cuò)誤定位 對(duì)應(yīng)Handler對(duì)應(yīng)的options字段

    $user->getErrors(); // return Structure\Error[]
  • 輸出

    • 全量輸出會(huì)進(jìn)行轉(zhuǎn)換和default賦值
    • 全量輸出不進(jìn)行過濾
    $user->output(); // return array

    $user->output(true); // 全量輸出
  • 清洗
    $user->clean(); // 默認(rèn)不裝載raw數(shù)據(jù)

    $user->clean(true); // 裝載raw數(shù)據(jù)

補(bǔ)充

  • Handler 接受自定義注冊(cè)
    \Structure\Handler::register();
  • StructureException
    try {
        // ...                          
    }catch (\Structure\Exceptions\StructureException $exception){
        $exception->getPosition(); // 錯(cuò)誤定位信息
        $exception->getMessage(); // Structure Exception [{position info}]
        $exception->getCode(); // 始終以-666返回
    }
2633 5 1
5個(gè)評(píng)論

Tinywan

感謝分享!

admin

不錯(cuò)

torrise

感謝分享,枚舉類的規(guī)則如何處理

  • chaz6chez 2022-11-11

    之前在寫這個(gè)組件的時(shí)候沒有考慮枚舉類,其實(shí)可以自行實(shí)現(xiàn)handler,然后注冊(cè)進(jìn)入使用

powerbowen

感謝分享,這個(gè)東西看上去不錯(cuò)
以下是提出的一些關(guān)于使用場(chǎng)景的問題
1.入?yún)⑹嵌嗑S數(shù)組的情況是是否有相應(yīng)的驗(yàn)證規(guī)則,如下

$a = [
    ['a' => [1,2,3,'child' => [666]]]
];

2.在很多業(yè)務(wù)場(chǎng)景中前端會(huì)傳過來很多亂七八糟的數(shù)據(jù),如果需要參數(shù)僅需要某些字段的時(shí)候是否有相關(guān)的校驗(yàn)方式

//現(xiàn)在的
$liat = [
    'name' => 'xxx',
    'mobile' => 'xxx',
    'pwd' => 'xxx'
];
$model->name = $list['name'];
$model->mobile = $list['mobile'];

//增加驗(yàn)證后就可以驗(yàn)證存在非name和mobile字段,直接提示參數(shù)異常
$model->attributes = $list;

望指導(dǎo)

  • chaz6chez 2022-11-11

    你是說不能確定哪些參數(shù)需要驗(yàn)證,整個(gè)字段的驗(yàn)證是隨機(jī)的?
    如果是固定字段,但有可能客戶端傳來的參數(shù)并不一定傳入該參數(shù)的話,其實(shí)可以用skip標(biāo)簽

  • powerbowen 2022-11-11

    不好意思,上面的沒有表述清楚,我現(xiàn)在有修改個(gè)人資料接口,是以數(shù)組形式傳過來的鍵值對(duì)參數(shù)列表,比如姓名、手機(jī)號(hào),性別等,在賦值的時(shí)候我要判斷有什么賦值什么
    理想情況是直接把給過來的東西進(jìn)行數(shù)據(jù)驗(yàn)證,然后塞到屬性里即可,但是對(duì)方可能把其它字段拿過來進(jìn)行試探,比如修改企業(yè)id,修改角色,修改密碼
    我這個(gè)修改資料接口僅支持修改姓名、性別、手機(jī)號(hào)、郵箱、身份證,如接收到的請(qǐng)求數(shù)據(jù)存在這些以外的數(shù)據(jù)就進(jìn)行報(bào)錯(cuò)
    不知道我表述的清不清晰

  • chaz6chez 2022-11-11

    那就嵌套一下唄,就是這個(gè)數(shù)組再創(chuàng)建一個(gè)struct,這個(gè)struct對(duì)象是外層struct的某個(gè)屬性,然后外層用func的方式獲取內(nèi)層struct的message

Tinywan

  • 暫無評(píng)論
年代過于久遠(yuǎn),無法發(fā)表評(píng)論

chaz6chez

5174
積分
0
獲贊數(shù)
0
粉絲數(shù)
2018-11-16 加入
??