從熱門框架的內建 Validation 機制,認識常見資料驗證規則

Johnliutw
JohnLiu 的軟體工程思維
9 min readFeb 18, 2024
Photo by Leon Dewiwje on Unsplash

在各種應用程式的開發過程中,資料的正確性和安全性是不可或缺的一部分。尤其是當提到 API 服務時,有效的資料驗證規則不僅能保護系統免受無效或惡意參數的傷害,還能確保使用者體驗的一致性和可靠性。

這篇文章將深入探討 Laravel 框架提供的多種 validation 規則,這些規則讓我們能夠精確地定義和強化資料的正確性。

從基礎的 required 和 string 規則,到更複雜的如 bail 和 ascii 規則,筆者將這些規則整理成約 11 大項,來分別介紹我們應可以用怎麼樣的方式,檢核資料的正確性。

這篇文章是以 Laravel 的 validation 機制為例,但無論是有沒有 Laravel 的開發經驗,都可以了解資料驗證可以進行的方式。

1. 資料類型

  • array、string、integer、json,檢查是否為字面上之資料類型
  • boolean,就是 boolean,但支援 true、false、0、1
  • numeric,使用 php 的 is_numeric() 函式確認為數字
  • file,須為檔案
  • date,使用 PHP 的 date_parse() 和 checkdate() 檢查,資料是否為合法 date 格式
  • nullable,允許 null,不過偏程式碼意圖的存在,沒有真正功能
  • hex_color,須符合標準的色碼格式,請參考:

2. 網路位址

  • active_url,從 DNS server 拿 A 或 AAAA 紀錄,確認是否網址還在
  • ip、ipv4、 ipv6,驗證資料須為 IP、IPv4、IPv6 格式
  • mac_address,確認是否為 Mac address
Photo by Eric Rothermel on Unsplash

3. 時間日期

  • after、after_or_equal、before、before_or_equal,須在指定日期之後或之前
  • date_equals,須符合指定日期
  • date_format,須符合指定日期格式
  • timezone,必須是符合 ISO 3166–1 或 PHP 自定義的 Datetime Constant 格式

4. 字串

  • doesnt_start_with、starts_with、doesnt_end_with、end_with,確認字串的開頭與結尾
  • lowercase、uppercase,確認字串的大小寫
  • regex、not_regex,確認字串符合指定的 regex 規則

5. Email

雖然在 rule 上只有 email 一個,但支援多種模式,且都有重要的意義,來一一介紹之。補充,其底層使用 Egulias 的 Email Validator

  • rfc,預設模式,針對 RFC 5321 + 5322,包括使用者名稱格式、域名、. 符號的使用和長度。
  • strict,更嚴格,針對所有 warning 層級的問題做檢查,推薦查看 warning 表:
  • dns,檢查 dns 是否為本地域名,例如 localhost, local, home…等等
  • spoof,檢查是否有不安全的 unicode 字元
  • filter,使用 PHP 的 filter_var 的 FILTER_VALIDATE_EMAIL 模式過濾,但有無法滿足 RFC 5321 的情形,推薦參考:
  • filter_unicode,同 filter,但允許 unicode 模式

6. 檔案

  • dimensions,支援 min/max + width/height,和 ratio 比例模式,也會檢查是否為檔案。MimeType 是 svg+xml 與 svg 會直接跳過
  • extensions,檢查副檔名,但仍不夠安全,因為使用者可以自製副檔名,建議作為備援機制檢查
  • mimes,必須是圖片類型,目前支援: jpg, jpeg, png, bmp, gif, svg, webp
  • mimetypes,透過猜檔案的方式,來驗證須符合指定 MIME types
Photo by Dylan Ferreira on Unsplash

7. 二次檢核

  • accpted_if、accepted,常用在服務條款的情境中,能接受 yeson1true,或任意指定的其他值
  • declined_if、declined,同 accepted 的情境,支援 nooff0false,或任意指定的其他值
  • confirmed,再度確認,常用在 password 的情境

8. 區間

  • between,資料要在指定 min 與 max 區間
  • digits、digits_between、max_digits、min_digits,指定字串資料的長度,能有最大、最小或區間等模式
  • size,可以根據資料類型判斷,指定欄位需要有的長度
  • decimal,指定小數點應到第幾個位置
  • gt、gte、lt、lte,可以確保大於或小於其他欄位或特定值,一定要同類型的資料
  • in、in_array、not_in,類似 SQL where in 邏輯,限制值,需被驗證的資料值,只能在指定的資料集中
  • max、min,最大與最小值
  • multiple_of,值必須是給定值的倍數,例如時間間隔、固定數量為一個單位,每 1000 股為一張…等等

9. 與其他資料相關聯

  • different、same,欄位應和表單中,特定另一欄位值不同或相同。常見的使用情境像是會員功能的使用者名稱與密碼、銀行軟體的帳號與身分證字號、email 的接收與發送者。
  • distinct,假設資料是一個陣列,並且內含物件,可以確認這些物件群中,特定欄位必須是唯一值,支援 strict 和 case_sensitive 模式
  • unique,可直接連接 DB 檢核,是否為唯一值
Photo by Paige Cody on Unsplash

10. 存在與不存在

這部分通常可以分成 4 種主要類別:

  1. required,標記特定欄位是必需要存在的欄位,且不能是 null、空字串、空陣列
  2. missing,標記特定欄位是不能存在的欄位
  3. prohibited,標記特定欄位是不能存在的欄位,但能允許 null、空字串、空陣列
  4. exclude,標記特定欄位直接過濾

再來基於這些類別,通常有能拆分 4 種不同模式

  1. _if、_unless: 全類別皆有,符合條件才執行資料驗證邏輯
  2. _with、_with_all、_without、_without_all,除了 prohibited,其他類別大致都有,是檢查要特定欄位或欄位們存在才會執行
  3. _if_accepted,required 才有,主要搭配文章前面講述過的 accepted 方式
  4. _array_keys,required 才有,檢查特定物件要有特定 key 值

最後,是其他的存在類型的驗證規則:

  • exists,可以直接找欄位的值,是否存在特定表格中,能夠支援客製化的 query
  • filled,類似 required,不過是非必填,但如果有傳,則一定要有資料,使用 required 的驗證邏輯
  • present,確認欄位有存在即可
Photo by Tianyi Ma on Unsplash

11. 軟體工程導向

  • alpha, alpha_data, alpha_num,unicode alphabetic 文字,包含限制 ascii 字元範圍內的模式
  • ascii,就是 ascii 文字
  • password, current_password,會利用框架的 auth 功能,拿取當前 session 中 user 在儲存位置的 password 做比對。
  • bail,由於框架的部分 validation 規則會讀取資料庫,因此可以設定這個 early break 模式,讓第一個 validation fail 就中止驗證,不需要不必要的資料庫資源消耗
  • enum,支援 laravel enum 類別

感謝您花時間閱讀這篇文章!如果您覺得這些分享對您有幫助,請不吝給予一個👏按讚,並追蹤我的 Medium,以便於不錯過未來的精彩內容。

此外,我也邀請您來追蹤我的粉絲專頁

John Liu — Software Thinking

我會定期分享關於軟體開發、程式設計思維以及最新科技趨勢的見解和討論。這是一個我們可以進一步交流想法和經驗的平台,我非常期待與您一起成長和學習。

再次感謝您的閱讀和支持,讓我們在 Medium 和 Facebook 上保持聯繫吧!

--

--

Johnliutw
JohnLiu 的軟體工程思維

熱愛軟體全端技術開發,較為擅長 Web 領域,並有多年線上與線下授課經驗,專精軟體新手教學。 相關合作: johnliutw@hotmail.com