filter_var_array 使用浮点数会导致结果中有太多小数位
filter_var_array with floats causes too many decimal places in result
我对 filter_var_array 函数有问题,特别是 'FILTER_VALIDATE_FLOAT' 标志,returns 我浮动的小数位太多
代码优先:
if (property_exists($this->rawRequest, $varName)) {
$res = filter_var_array($this->rawRequest->$varName, FILTER_VALIDATE_FLOAT);
}
这是我的代码,我在其中验证通过 JSON
从客户端收到的参数
rawRequest 是一个 stdClass,如下所示(使用 var_export 打印):
stdClass::__set_state(
array(
'Action' => 'CreateObject',
'Template' => 'none',
'LatLng' => array (
0 => '48.14914653539144',
1 => '11.577623201171932',
)
)
'LatLng'参数经过filter_var_array过滤后,结果如下:
'LatLng' => array (
0 => 48.149146535391433732957206666469573974609375,
1 => 11.5776232011719315551090403459966182708740234375,
)
为什么会这样?
我什至无法用 round() 解决这个问题,将类型转换为浮点数、字符串再返回到浮点数,我尝试减去 0.00000001,然后再次添加 0.00000001,但没有任何帮助
更新:
我在同一台机器上写了以下小测试脚本,同一个 apache 服务器:
<?php
$test = '48.158308230848306';
$test2 = (float) $test;
$test3 = floatval($test);
echo($test2);
echo('<br />');
echo($test3);
exit(0);
输出在这里:
48.158308230848
48.158308230848
这正是我所期望的
我用我的产品代码重新测试了它并使用了 floatval() 和类型转换来浮动,但它没有工作。我不知道,唯一的区别是在产品代码中输入是 json,我用下面的代码解析它:
json_decode(file_get_contents('php://input'))
所以,我终于找到了问题的答案
问题从来都不是 filter_var_array()
功能,实际上,问题发生得更早。
通过 file_get_contents("php://input")
检索 POST 参数后,一切仍然正常。
但是当我用 json_decode()
解码返回的字符串时,浮点值在这个过程中被序列化,导致更高的精度。
我找到了两种 "solve" 方法:
- 更改php.ini中的"serialize_precision"参数(我的默认是100,设置成和我的"precision"参数一样就成功了)
我不推荐这种方法,因为改变这个参数的影响可能在其他地方是毁灭性的
- 将请求中的浮点数用引号引起来
因此,将 JSON {"test": 48.58495135846} 更改为 {"test": "48.58495135846"}
这阻止了浮点数的序列化,因为它现在实际上是一个字符串
希望这对其他人有帮助,也许这已经是常识,但我对此感到很紧张。
我对 filter_var_array 函数有问题,特别是 'FILTER_VALIDATE_FLOAT' 标志,returns 我浮动的小数位太多
代码优先:
if (property_exists($this->rawRequest, $varName)) {
$res = filter_var_array($this->rawRequest->$varName, FILTER_VALIDATE_FLOAT);
}
这是我的代码,我在其中验证通过 JSON
从客户端收到的参数
rawRequest 是一个 stdClass,如下所示(使用 var_export 打印):
stdClass::__set_state(
array(
'Action' => 'CreateObject',
'Template' => 'none',
'LatLng' => array (
0 => '48.14914653539144',
1 => '11.577623201171932',
)
)
'LatLng'参数经过filter_var_array过滤后,结果如下:
'LatLng' => array (
0 => 48.149146535391433732957206666469573974609375,
1 => 11.5776232011719315551090403459966182708740234375,
)
为什么会这样?
我什至无法用 round() 解决这个问题,将类型转换为浮点数、字符串再返回到浮点数,我尝试减去 0.00000001,然后再次添加 0.00000001,但没有任何帮助
更新:
我在同一台机器上写了以下小测试脚本,同一个 apache 服务器:
<?php
$test = '48.158308230848306';
$test2 = (float) $test;
$test3 = floatval($test);
echo($test2);
echo('<br />');
echo($test3);
exit(0);
输出在这里:
48.158308230848
48.158308230848
这正是我所期望的
我用我的产品代码重新测试了它并使用了 floatval() 和类型转换来浮动,但它没有工作。我不知道,唯一的区别是在产品代码中输入是 json,我用下面的代码解析它:
json_decode(file_get_contents('php://input'))
所以,我终于找到了问题的答案
问题从来都不是 filter_var_array()
功能,实际上,问题发生得更早。
通过 file_get_contents("php://input")
检索 POST 参数后,一切仍然正常。
但是当我用 json_decode()
解码返回的字符串时,浮点值在这个过程中被序列化,导致更高的精度。
我找到了两种 "solve" 方法:
- 更改php.ini中的"serialize_precision"参数(我的默认是100,设置成和我的"precision"参数一样就成功了)
我不推荐这种方法,因为改变这个参数的影响可能在其他地方是毁灭性的 - 将请求中的浮点数用引号引起来
因此,将 JSON {"test": 48.58495135846} 更改为 {"test": "48.58495135846"}
这阻止了浮点数的序列化,因为它现在实际上是一个字符串
希望这对其他人有帮助,也许这已经是常识,但我对此感到很紧张。