摘要:下面這段代碼是自帶的表單驗證的語法,不太了解的可以先查看文檔也可以使用替換和我們期望的結(jié)果是能校驗字段最小值是,最大值是當(dāng)我單元測試的時候發(fā)現(xiàn),竟然校驗通過了單元測試代碼文檔分析我們看一下文檔驗證中的字段必須具有最小值。
下面這段代碼是Laravel自帶的表單驗證的語法,不太了解的可以先查看文檔
"group_num" => "min:1|max:21" // 也可以使用between替換min和max
我們期望的結(jié)果是能校驗group_num字段最小值是1,最大值是21
but ?。?!
...
當(dāng)我單元測試的時候發(fā)現(xiàn),竟然校驗通過了!
// 單元測試代碼 $warehouseId = 1; $prods = [ [ "prod_id" => 1, "group_num" => 111, "location" => 1, ] ]; $warehouseLogic = new WarehouseLogic(); $result = $warehouseLogic->addProds($warehouseId, $prods); $this->assertEquals(ErrSvc::ERR_OK, $result["code"]);文檔分析
我們看一下文檔
min:value驗證中的字段必須具有最小值。字符串、數(shù)字、數(shù)組或是文件大小的計算方式都用 size 方法進(jìn)行評估。
文章提到數(shù)字使用size方法進(jìn)行評估,我們看一下size方法的文檔
size:value代碼分析驗證的字段必須具有與給定值匹配的大小。對于字符串來說,value 對應(yīng)于字符數(shù)。對于數(shù)字來說,value 對應(yīng)于給定的整數(shù)值。對于數(shù)組來說,
size 對應(yīng)的是數(shù)組的 count 值。對文件來說,size 對應(yīng)的是文件大?。▎挝?kb )。
文檔一切正常,我們翻一翻代碼試著分析下原因
我們找到驗證類的文件并打開:vendorlaravelframeworksrcIlluminateValidationValidator.php
大約在1180行,我們看到validateMin()方法
validateMin()第一行代碼,是對參數(shù)個數(shù)進(jìn)行驗證的,可以pass掉第二行代碼,調(diào)用了getSize()方法,并對getSize()返回結(jié)果直接進(jìn)行大小比較,問題很有可能就出現(xiàn)在getSize()方法身上
我們看一下getSize()的代碼
getSize()我們可以看到if里面判斷了如果值是數(shù)字類型并且$hasNumeric就直接返回原始值,如果返回原始值的話,validateMin()方法應(yīng)該會正確校驗,所以if條件應(yīng)該是不成立的
原因很可能就在$hasNumeric這個變量上
$hasNumeric調(diào)用了$this->hasRule($attribute, $this->numericRules)方法,并傳了兩個參數(shù)過去$attribute:當(dāng)前屬性名
$this->numericRules:["Numeric", "Integer"]
然后我們看一下$this->hasRule()方法究竟做了什么?
hasRule方法直接調(diào)用了$this->getRule()方法,并且將參數(shù)原封不動傳遞過去
我們看一下getRule()方法干了什么?
getRule()我們已知$attribute是當(dāng)前字段名,比如文章舉例用的字段group_num
$this->rules其實就是字段+校驗規(guī)則拼裝的數(shù)組,格式如下:
既然第一個if語句的兩個變量都知道了,我們就能判斷出第一個條件是不成立的,我們繼續(xù)看接下來的代碼
代碼是對當(dāng)前需要校驗字段的規(guī)則進(jìn)行遍歷,并且格式化
list($rule, $parameters) = $this->parseRule($rule);假設(shè)是上圖中的group_num字段,他有3個校驗規(guī)則,分別是:required、min、max
第一次循環(huán)$rule就是Required,$parameters為空
第二次循環(huán)$rule就是Min,$parameters就是[1]
我們會發(fā)現(xiàn)parseRule($rule)后,會對規(guī)則進(jìn)行in_array的判斷,$rules是參數(shù)(["Numeric", "Integer"])上文有寫
假設(shè)我們此時的字段是group_num:第一個規(guī)則是required,條件不成立;
第二個規(guī)則是Min,條件依然不成立;
第三個規(guī)則是Max,條件還是不成立!
getRule()返回值:條件都不成立,方法走完,沒有任何返回值,返回值為null
hasRule()返回值:回到hasRule()方法,會對getRule()方法值進(jìn)行is_null(),并進(jìn)行邏輯非處理(!),所以返回值為false
我們接著回到getSize()方法,此時我們就知道$hasNumeric的值是false
所以下面的if條件都不成立,最后Laravel使用mb_strlen()對我們數(shù)字類型的值進(jìn)行了長度計算?。?!
解決問題既然我們知道原因在于Laravel對當(dāng)前字段所有規(guī)則進(jìn)行了in_array($rule, ["Numeric", "Integer"])
所以解決思路就是,如果我們要對字段進(jìn)行大小進(jìn)行范圍校驗,我們需要把規(guī)則修改成:
"group_num" => "integer|min:1|max:21"
所以文章開頭的校驗,對于數(shù)值類型的字段,是錯誤的!
其實這不是一個BUG,單純的是Laravel的校驗機(jī)制,不過Laravel文檔寫的很模糊!
所以大家在開發(fā)的時候記得一定要認(rèn)真測試!
原文在自己的博客:Laravel一次單元測試發(fā)現(xiàn)的’BUG’,分析并解決問題 - 木魚博客
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/28914.html
摘要:最近在項目中引用了一個新標(biāo)準(zhǔn)上傳附件的插件,使用過程中發(fā)現(xiàn)了一個很有意思也很頭疼的問題,第一次點擊時瞬間就可以打開文件選擇框,之后再點擊則需要等待恐怖的以上備注使用的是瀏覽器版本這是核心部分代碼,經(jīng)過二次封裝的。 最近在項目中引用了一個html5新標(biāo)準(zhǔn)上傳附件的插件,使用過程中發(fā)現(xiàn)了一個很有意思也很頭疼的問題,第一次點擊時瞬間就可以打開文件選擇框,之后再點擊則需要等待恐怖的8s以上(備...
摘要:如果我們把非布爾值作為條件呢打開控制臺并運行上述代碼,會打印說明條件為真值。在中,真值指的是在布爾值上下文中轉(zhuǎn)換后的值為真的值。兩個能夠建立元素間一一對應(yīng)的集合稱為互相對等集合。 showImg(https://segmentfault.com/img/bVbtSvt?w=720&h=360); 為了保證可讀性,本文采用音譯而非直譯。 Javascript 一直是神奇的語言。 不相信我...
摘要:今天用更改了的命名空間名字,然后又用恢復(fù)到了原來的命名空間名。結(jié)果直接導(dǎo)致以下錯誤問題解決確定你的引導(dǎo)程序沒問題在項目根目錄執(zhí)行命令解決方案來自傳送門為什么要執(zhí)行,參考深入 今天用php artisan app:name 更改了app的命名空間名字,然后又用git恢復(fù)到了原來的App命名空間名。 結(jié)果直接導(dǎo)致以下錯誤:Fatal error: Uncaught exception Re...
摘要:原文首發(fā)于我的個人網(wǎng)站卡頓問題出現(xiàn)背景中主要耗能設(shè)置為折線圖軸數(shù)據(jù)量控件最開始軸為類目軸,最近根據(jù)情況想改為時間軸卡頓主要表現(xiàn)在顯示和拖動時。初步分析是為導(dǎo)致,因為切換回后就卡頓問題消失。 原文首發(fā)于我的個人網(wǎng)站: https://lonhon.top/ 卡頓問題出現(xiàn)背景: ECharts^4.0.4 + Vue^2.5.9 option中主要耗能設(shè)置為:折線圖 + Y軸2 + se...
閱讀 1538·2023-04-26 00:25
閱讀 923·2021-09-27 13:36
閱讀 934·2019-08-30 14:14
閱讀 2185·2019-08-29 17:10
閱讀 1018·2019-08-29 15:09
閱讀 1954·2019-08-28 18:21
閱讀 971·2019-08-26 13:27
閱讀 984·2019-08-26 10:58