PHP浮点数字符串转换的坑

问题描述

今天上班,技术客服反馈系统无法给微信支付用户退款,提示:“订单金额或退款金额与之前请求不一致,请核实后再试”。

问题排查

根据提供信息查询日志发现确实有这样的问题。首先排查了订单支付数据没有问题,其次看了是否有没有同事修改了代码。在排查代码的过程中发现关于退款金额的计算有些奇怪,php实现的部分代码如下:

refund->byOutTradeNumber(
        $order->id,
        'REFUND' . $order->id,
        $fee * 100,
        $refund_fee ? $refund_fee * 100 : $fee
    );
    ...
?>

byOutTradeNumber方法的第三、四参数要求是int型,而传递过来的$fee参数是string类型,发生类型强制转换就出问题了。

通过以下示例代码来复现一下:

 $fee * 100])); // string(26) "{"fee":3279.9999999999995}"
    var_dump(json_encode(['fee' => round($fee * 100)])); // string(26) "{"fee":3279.9999999999995}"

?>

根据以上结论,在系统调用byOutTradeNumber方法时参数强制装换成int型就会把小数部分去掉,这样就出现金额不一致问题了。其本质原因是:float(32.80)在内存中实际存储的是3279.9999999999995,导致类型装换之后结果不正确。这个在PHP编程中需要特别注意。

解决方法

分析到这里问题解决就容易了,直接上代码:


ps:PHP语言存在这个问题,其它语言同样也存在这个问题,语言之间语法不同,编程思想、编程经验是通用的。
个人博客链接:https://linjinwei.com/php/20190908081309.html

你可能感兴趣的:(PHP)