PHP Swoft2 框架精華系列:Validator 校驗器詳解

文章目錄

    • 校驗器
      • 校驗器類型
      • @Validate 注解
        • 屬性說明
        • 校驗器校驗主要流程
        • 系統校驗器每個屬性存儲結構
        • 校驗器規則定義,注解、注解解析器定義
        • 校驗器注解使用
      • 實現一個自定義的校驗器
        • 校驗器注解
        • 校驗器注解解析器
        • 校驗器規則
        • 系統校驗器
        • Controller/Action 綁定校驗器

校驗器

校驗器是 swoft2 中一個常用的組件。

校驗器在 RPC服務、WS服務、HTTP 服務中均有涉及,用來校驗客戶端上傳到服務端的數據是否合法。

校驗器類型

校驗器一般分為兩種,系統校驗器,和自定義校驗器。

系統校驗器是通過 @Validator 標簽進行注解的一個校驗器類(沒有方法只有屬性),每個屬性上通過不同的注解(如:@Length @IsString )來說明校驗時候參數要符合的規則。

自定義校驗器,同樣需要 @Validator 標簽對校驗的類進行注解,但是類必須要實現 ValidatorInterface 接口,只有實現接口validate(array $data, array $params),才會稱為自定義校驗器(源碼中有此判斷,參見:src/Annotation/Parser/ValidatorParser.php)。注意自定義校驗器,只會校驗 body 中數據,且自定義校驗器,只會使用 body 中數據和 params,其他 @Validate 屬性,并不會使用。

/*** Class CustomerValidator** @since 2.0** @Validator(name="userValidator")*/
class CustomerValidator implements ValidatorInterface
{/*** @param array $data		這是自定義校驗器中* @param array $params** @return array* @throws ValidatorException*/public function validate(array $data, array $params): array{$start = $data['start'] ?? null;$end   = $data['end'] ?? null;if ($start === null && $end === null) {throw new ValidatorException('Start time and end time cannot be empty');}if ($start > $end) {throw new ValidatorException('Start cannot be greater than the end time');}return $data;}
}

@Validate 注解

屬性說明
/*** Class** @since 2.0** @Annotation* @Target("METHOD")* @Attributes({*     @Attribute("validator", type="string"),*     @Attribute("fields", type="array"),*     @Attribute("params", type="array"),*     @Attribute("message", type="string"),* })*/
class Validate {}

以上為 @Validate 注解的參數要求,具體說明見下表:

注解參數參數類型是否必須備注
validator字符串已經定義好的校驗器的名字
fields數組校驗器中的屬性(對應請求中的參數)。
不指定,默認校驗校驗器中所有屬性。
如果指定的值在校驗器中不存在,那么控制器中仍然可以接收到參數,但是不會有任何校驗!!!
unfields數組不進行校驗的屬性
params數組用在自定義校驗器中,用戶手動傳遞到校驗器的數據
注:自定義校驗器時候才會使用
message字符串校驗失敗時候提示信息
type字符串校驗數據所在請求對象中的位置(get/body/path)

@Validate 注解用于 method 上,示例:

// 示例1:通過系統默認校驗器,校驗 post 請求中的參數
/*** @RequestMapping("account")* @param Request $request* @param Response $response* @return Response* @throws InvalidArgumentException* @Validate(validator="userValidator", fields={"name", "password"}, type="body")*/
public function account(Request $request, Response $response): Response;// 示例2:通過系統默認的校驗器校驗自定義 path 參數/*** @RequestMapping(route="/[list-{page}.html|index.html]", params={"page"="[2-9]\d*|1\d+"}, method={"GET"})* @View("home/index")* @Validate(validator=PageListDto::class, fields={"page", "size"}, type="path")** @param Request $request* @param Response $response* @return Response*/
public function index(Request $request, Response $response): Response

注意:@Validate 的 type 參數十分重要,默認值為 body,也就是默認校驗 post 請求參數。如果是校驗 get 參數,或者自定義 path 中的自定義參數,必須要寫明類型。否則校驗出錯。

校驗器校驗主要流程

以 HTTP 服務為例,可以參照 http-server 組件中的 src/Middleware/ValidatorMiddleware.php 中間件,此中間件可以通過定義核心 Bean 的方式,將其掛載到 HTTP 服務上。從相關代碼可以看出,中間件運行期間,通過 ValidateRegister::getValidates()方法提取訪問接口上綁定的校驗器相關信息。

class ValidatorMiddleware implements MiddlewareInterface
{/*** @param ServerRequestInterface  $request* @param RequestHandlerInterface $handler** @return ResponseInterface* @throws ValidatorException*/public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface{// 獲取路由匹配結果,如果未匹配成功,此中間件不做處理,交給下一個中間件。/* @var Route $route */[$status, , $route] = $request->getAttribute(Request::ROUTER_ATTRIBUTE);if ($status !== Router::FOUND) {return $handler->handle($request);}// 如果路由匹配成功,獲取路由綁定的處理器(controller/action)// Controller and method$handlerId = $route->getHandler();[$className, $method] = explode('@', $handlerId);// 獲取 controller/action 方法上通過注解綁定的校驗器(可以多個)// Query validates$validates = ValidateRegister::getValidates($className, $method);// 如果沒有,說明不用校驗,交給下一個中間件處理if (empty($validates)) {return $handler->handle($request);}// 獲取校驗涉及的相關數據$data  = $request->getParsedBody();$query = $request->getQueryParams();$path  = $route->getParams();// ParsedBody is empty string$parsedBody    = $data = empty($data) ? [] : $data;$notParsedBody = !is_array($data);if ($notParsedBody) {$parsedBody = [];}// 獲取校驗器組件的實例對象/* @var Validator $validator */

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/909772.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/909772.shtml
英文地址,請注明出處:http://en.pswp.cn/news/909772.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MySQL 類型轉換與加密函數深度解析

MySQL 類型轉換與加密函數深度解析 一、類型轉換函數詳解 1. 顯式類型轉換 CAST 函數 CAST(expression AS type)支持類型:BINARY, CHAR, DATE, DATETIME, TIME, DECIMAL, SIGNED [INTEGER], UNSIGNED [INTEGER]示例:SELECT CAST(2023-08-15 AS DATE);…

FPGA基礎 -- Verilog 行為級建模之條件語句

Verilog 的行為級建模(Behavioral Modeling)中的條件語句(Conditional Statements),逐步從基礎到實際工程應用,適合有RTL開發基礎但希望深入行為建模的人。 一、行為級建模簡介 行為級建模(Beh…

linux618 NFS web.cn NFS.cn backup.cn

權限問題 推測 ssh root登錄失敗 root192.168.235.100s password: ???????? root192.168.235.100s password: ???????? root192.168.235.100s password: ???????? root192.168.235.100s password: ???????? root192.168.235.100s password: …

氧化鐿:稀土科技的“夜視高手”

氧化鐿(Yb?O?)是一種重要的稀土氧化物,這種略帶黃色的粉末,既不像黃金那樣耀眼,也不像稀土家族里的“明星”如釹、鋱那樣廣為人知,卻在背后默默支撐著許多高科技產業,特別是在紅外技術領域&am…

class對象【C#】2025復習

對象 西方思想是:復雜的事讓秘書去做就行。老板只需簡單的下達命令。 代碼格式如下 秘書類型 秘書A new 秘書類型(); . 秘書A.開始工作(); // 調用實例對象的方法。 特別注意的是,程序只會用到 秘書A,秘書B&…

Qt程序啟動動畫

一、Qt有3種方式實現程序啟動動畫(介紹) 1、QSplashScreen 靜態圖片(png、jpg等格式) 2、QMovie 動態圖片(gif格式) 3、QAxWidget 視頻(swf格式) 1.QSplashScreen 靜態圖片(png、jpg等格式) //創建啟動動畫類實例 QSplashScreen splash(QPixmap(&qu…

貪心算法經典問題

目錄 貪心思想 一、Dijkstra最短路問題 問題描述: 貪心策略: 二、Prim 和 Kruskal 最小生成樹問題 Prim 算法: Kruskal 算法: 三、Huffman樹問題 問題描述: 貪心策略: 四、背包問題 問題描述&a…

零知開源——STM32F4實現ILI9486顯示屏UI界面系列教程(一):電子書閱讀器功能

本教程將詳細介紹如何在零知增強板上使用3.5寸ILI9486顯示屏實現電子書閱讀器功能。我們將使用LVGL庫構建用戶界面,并實現翻頁、進度顯示等核心功能。 目錄 一、硬件連接 二、軟件UI組件實現 三、零知IDE配置 四、演示效果 五、常見問題解決 六、總結與擴展 一…

支持selenium的chrome driver更新到137.0.7151.119

最近chrome釋放新版本:137.0.7151.119 如果運行selenium自動化測試出現以下問題,是需要升級chromedriver才可以解決的。 selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This version of ChromeDriver only s…

架構下的最終瓶頸:數據庫如何破局?

在分布式系統和云原生架構逐漸成熟的當下,我們已能夠靈活擴展計算資源、水平擴展服務節點、拆分業務模塊等。然而,在經歷過多輪架構優化之后,數據庫常常成為系統的“最后瓶頸”。尤其當數據量、并發量、實時性要求劇增時,數據庫即…

湖北理元理律師事務所小微企業債務重組方案:司法與經營的共生邏輯

小微企業債務問題常陷入“救企業還是保老板”的困局。湖北理元理律師事務所為某汽車零部件供應商設計的“經營性債務重組”方案,提供了創新解題思路。 核心矛盾拆解 該企業面臨三重困境: 矛盾類型 具體表現 法律風險等級 擔保鏈危機 老板個人擔保牽…

FastAdmin退出登錄不提示的修改方法

修改退出登錄后的提示行為 在FastAdmin中,默認退出登錄后會顯示"退出成功"的提示信息并跳轉頁面。要實現不顯示提示信息直接跳轉,可以通過以下方式修改: 方法一:修改控制器邏輯 找到application/admin/controller/Log…

工信部發布《中國工業軟件產業發展研究報告(2025)》:PLM壟斷加劇,Ai為國產PLM軟件發展契機

在6月17日上午舉行的2025南京軟件大會開幕式上,工信部電子第五研究所現場發布《中國工業軟件產業發展研究報告(2025)》(以下簡稱《研究報告》),并從工業軟件產業發展現狀、產業發展趨勢,以及我國…

Flutter JSON解析全攻略:使用json_serializable實現高效序列化

引言:為什么我們需要JSON序列化工具? 在現代移動應用開發中,與服務器進行數據交互是必不可少的功能。JSON(JavaScript Object Notation)作為一種輕量級的數據交換格式,因其易讀性、簡潔性和廣泛支持性&…

shelve模塊的使用

shelve模塊的使用 1. 什么是Shelve2. Shelve模塊的數據存儲與讀取3. Shelve的讀取數據4. Shelve模塊的高級操作_ Shelve的數據更新和刪除5. 刪除操作可以使用del語句:6. Shelve的數據查詢和處理_使用for循環來遍歷Shelve對象中的所有鍵值對:7. Shelve模塊…

python大學校園舊物捐贈系統

目錄 技術棧介紹具體實現截圖系統設計研究方法:設計步驟設計流程核心代碼部分展示研究方法詳細視頻演示試驗方案論文大綱源碼獲取/詳細視頻演示 技術棧介紹 Django-SpringBoot-php-Node.js-flask 本課題的研究方法和研究步驟基本合理,難度適中&#xf…

Python爬蟲實戰:研究eventlet庫相關技術

1. 引言 在當今信息爆炸的時代,網絡上的數據量呈現出指數級增長的趨勢。從海量的網絡信息中獲取有價值的數據并進行分析,對于企業決策、學術研究以及個人興趣等方面都具有重要意義。網絡爬蟲作為一種自動化獲取網頁內容的技術手段,應運而生并得到了廣泛的應用。 網絡爬蟲(…

文字識別接口-智能文本處理-文字提取技術

文字識別接口,顧名思義,就是一種將圖像文字或手寫文字轉換為可編輯文本的技術。文字識別接口,基于深度學習算法與自主ocr核心實現多種場景字符的高精度識別與結構化信息提取,現已被廣泛應用于銀行、醫療、財會、教育等多個領域。 …

Redis的持久化機制詳細解析

Redis的持久化機制詳細解析 今天我們來聊聊Redis的持久化機制。想象一下,你正在玩一個非常精彩的游戲,突然斷電了,如果沒有存檔功能,所有的進度都會丟失,是不是很崩潰? Redis作為內存數據庫,同…

2025年SYN-CC混合攻擊防御實戰:某金融平臺抵御800Gbps雙重風暴實錄

“你以為防住SYN Flood就能高枕無憂?新型SYN-CC混合鏈正在撕裂傳統防御體系!” 一、事件現場:一場精準的“協議層絞殺” 2025年5月,某跨境支付平臺遭遇史上首次SYN-CC混合攻擊,峰值流量達 800Gbps,核心交易…