PHP 写的老屎山代码经常出现字符串转浮点数时小一点点的情况,排查了一晚上还没解决,请 v 友帮忙看看

2022-12-04 06:49:20 +08:00
 edis0n0

经常出现例如用户充值 1 元到账 0.994 元这类情况,导致用户余额无法购买商品

以下是充值部分业务逻辑代码:

$paidCredit = checkStringSign($invoice->credit);
if (isset($user->Credits) && $user->Credits != "") {
    $currentCredit = checkStringSign($user->Credits);
}
$currentCredit = $currentCredit + $paidCredit;
$updatedCredit = signString($currentCredit);
$updatePricePlanId = "";
if ($paidCredit > 99.5 && $user->RiskyScore < 1) {
    $updatePricePlanId = ",RiskyScore=0";
}
$query = "UPDATE users SET Credits = '$updatedCredit' $updatePricePlanId WHERE UserId = '$user->UserId'";
$objDBCD14->execute($query);
$comments = $out_trade_no;
$updateQuery = "update payments set Paid=1,TransactionId='$trade_no' WHERE PaymentId = '$out_trade_no' ";
$objDBCD14->execute($updateQuery);
$paymentId = $payments->PaymentId;
$objDBCD14->execute("INSERT INTO topUpRecords SET UserId ='$user->UserId', Credits = '$paidCredit', CreditsLeft = '$updatedCredit', Comments = '$comments'");

$invoice 中记录的金额是正确的 topUpRecords 中记录的金额就变成 0.994 了

但又不是 100%复现,排查了一晚上还没找出问题 checkStringSign 和 signString 接受的参数都是字符串,signString 内部逻辑是把字符串通过简单变换签名后将签名用 .{sign} 的格式附加在末尾,checkStringSign 内部逻辑是根据最后一个.分隔原文和签名,验签成功则返回原文,否则抛出错误,其中都不含显式的 cast 逻辑。

不熟悉 PHP ,之前写这个程序的人已经离职了,临时翻文档学的

3087 次点击
所在节点    PHP
26 条回复
proxychains
2022-12-05 09:14:43 +08:00
@msg7086 这是 AI?
msg7086
2022-12-05 09:49:44 +08:00
@proxychains 是啊,AI 帮你抓 Bug 。
lisxour
2022-12-05 10:37:39 +08:00
代码都不用看就知道不是浮点数精度问题,一个正常的语言,怎么可能 3 位小数就开始有精度问题。。。至少都是好几位以上才有这种问题
Twnysta
2022-12-05 11:00:57 +08:00
php 有专门的 bc 函数啊,算账都是用这个。直接对比不是自己跟自己不痛快吗?
vacker
2022-12-05 11:05:44 +08:00
@edis0n0 微信支付代码写多了,看到 0.994 直觉告诉我这是扣了手续费后的金额,哈哈
proxychains
2022-12-06 13:53:59 +08:00
@msg7086 已经通过图灵测试了...语气像是客服,有些地方感觉不对劲, 但找不到哪地方不对劲...

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/899919

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX