掃二維碼與項(xiàng)目經(jīng)理溝通
我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問(wèn)/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
最近,收到一個(gè)已經(jīng)在運(yùn)行的第三方開(kāi)發(fā)的項(xiàng)目,這個(gè)項(xiàng)目所在團(tuán)隊(duì)其他的項(xiàng)目經(jīng)常讓我們做一些技術(shù)支持服務(wù),其實(shí)技術(shù)支持服務(wù)就是考慮綜合性價(jià)比然后分包出去;可能是因?yàn)槲覀兏由瞄L(zhǎng),可能是因?yàn)槲覀兊男时容^高。
這個(gè)需求,其實(shí)是個(gè)問(wèn)題的大致情況就是,在一般情況下這個(gè)項(xiàng)目的支付及支付異步回調(diào)通知都是正常,但個(gè)別情況下是錯(cuò)誤的,比如說(shuō)32.30元。而這個(gè)問(wèn)題在用戶面前的表現(xiàn)就是:支付成功,但訂單依然是未支付狀態(tài);翻譯成技術(shù)術(shù)語(yǔ)就是,發(fā)起支付并支付成功,但回調(diào)處理出錯(cuò)了。
而且我們發(fā)現(xiàn)這個(gè)bug出現(xiàn)在的是在微信支付的子模塊中,因?yàn)榇蠹抑牢⑿胖Ц对谶M(jìn)行發(fā)送請(qǐng)求和校驗(yàn)的時(shí)候都有一個(gè)100的的倍率問(wèn)題,比如1元的金額,微信支付是100;而支付寶模塊是不存在這個(gè)異常的。
這個(gè)問(wèn)題在我本人在很久以前也遇到過(guò),而且在不久前其他的同學(xué)也出現(xiàn)過(guò)這個(gè)錯(cuò)誤,為此還發(fā)過(guò)一篇名為《開(kāi)發(fā)童鞋偶遇php作為弱類(lèi)型語(yǔ)言的坑》的文章,這篇文章描述的其實(shí)就是這個(gè)問(wèn)題。
比如以上的問(wèn)題,其實(shí)就是原開(kāi)發(fā)者在寫(xiě)這個(gè)校驗(yàn)的時(shí)候把接收到支付平臺(tái)通知的金額假設(shè)為$a(單位是分),而實(shí)際的金額為$b(單位是元)。比如上面的32.30元,那么$a應(yīng)該是3230,而$b就是32.30。如果$b直接乘以100然后轉(zhuǎn)為int。這里就會(huì)出問(wèn)題了。
看到上圖的結(jié)果,很明顯這樣是不行的,因?yàn)檗D(zhuǎn)成int后結(jié)果成了3229,而不是3230,顯然是不能夠校驗(yàn)通過(guò)的,于是以下代碼都不能夠正常執(zhí)行啦。
關(guān)于這個(gè)問(wèn)題,是因?yàn)閷?shí)際上對(duì)于機(jī)器來(lái)講,32.30并不是我們意識(shí)中的32.30,實(shí)際上是一個(gè)非常接近的一個(gè)數(shù),因此intval后就是3329了,這個(gè)可以搜索“php浮數(shù)點(diǎn)計(jì)算問(wèn)題”來(lái)查閱更多相關(guān)文章。
最后針對(duì)這個(gè)問(wèn)題,可以參考php的BC高精確度函數(shù)庫(kù)。包含了相加、比較、相除、相減、求余、相乘、n次方,、配置默認(rèn)小數(shù)點(diǎn)數(shù)目、求平方等;這些函數(shù)在涉及到電商及金融項(xiàng)目有關(guān)金錢(qián)的計(jì)算時(shí)比較有用。自 PHP 4.0.4,libbcmath 隨同 PHP 一起發(fā)布。該擴(kuò)展不需要任何外部的庫(kù)。
我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問(wèn)/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流