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