SimpleXML 奇怪的类型转换行为
今天,我们的一位客户投诉称,他的商店中的某些价格略低(准确地说是 1,- Kč)。当我开始调试时,我认为这可能是一个舍入错误。我们使用 SimpleXML 导入产品的价格,从代码的外观来看,一切似乎都是正确的,但是当我执行 dome var_dumps 时,一些价格确实四舍五入得很糟糕。有一个 ceil 函数将 54.6200
的上限保持为 54
。我知道我必须在使用所有 SimpleXML 值之前对其进行类型转换,但这种行为对我来说似乎很奇怪。似乎当我 ceil 存储在 SimpleXMLElement 的字符串节点中的浮点 vlaue 时,该值在 ceil 函数之前被类型转换为 int 。
好吧,这是我可以忍受的,该脚本是由一个可能不知道他需要从 SimpleXML 中输入所有内容的人编写的,但这对我来说仍然有点奇怪。有人知道这是怎么发生的吗? PHP 的 ceil 函数接受 float 作为参数,所以我希望该值被类型转换为 float,但在本例中,它是 int。 (您可能想运行代码)
<?php
$item = simplexml_load_string(
<<<ITEM
<Item>
<PHE>54.6200</PHE>
</Item>
ITEM
);
echo '<pre>';
echo $item->PHE.PHP_EOL; //54.6200
echo ceil($item->PHE).PHP_EOL; //54!!!
echo ceil((string)$item->PHE).PHP_EOL; //55
echo ceil((float)$item->PHE).PHP_EOL; //55
echo ceil('54.6200'); //55
echo PHP_EOL.PHP_EOL;
debug_zval_dump($item);
echo '</pre>';
zval_dump 的输出:
object(SimpleXMLElement)#1 (1) refcount(2){
["PHE"]=>
string(7) "54.6200" refcount(1)
}
Today one of our clients sent a complaint that on his shop, some prices are a little lower (1,- Kč precisely). When I started to debug, I thought this might be a rounding error. We're using SimpleXML to import products' prices and from the look of the code, everything seemed about right, but when I did dome var_dumps, some prices were really badly rounded. There is a ceil function which kept ceiling 54.6200
to 54
. I understand that I have to typecast all the SimpleXML values before using them, but this behavior seemed quite odd to me. It seems that when I ceil a floating point vlaue stored in a string node of SimpleXMLElement, the value gets typecasted to int before the ceil function.
Okay, that's something that I can live with, the script was programmed by somebody who probably didn't know that he needs to typecast everything from SimpleXML, but this still seems a bit odd to me. Does anybody know how is this happening? PHP's ceil function acceps float as an argument, so I'd expect the value gets typecasted to float, but in this case, it's int. (you might want to run the code)
<?php
$item = simplexml_load_string(
<<<ITEM
<Item>
<PHE>54.6200</PHE>
</Item>
ITEM
);
echo '<pre>';
echo $item->PHE.PHP_EOL; //54.6200
echo ceil($item->PHE).PHP_EOL; //54!!!
echo ceil((string)$item->PHE).PHP_EOL; //55
echo ceil((float)$item->PHE).PHP_EOL; //55
echo ceil('54.6200'); //55
echo PHP_EOL.PHP_EOL;
debug_zval_dump($item);
echo '</pre>';
Output of that zval_dump:
object(SimpleXMLElement)#1 (1) refcount(2){
["PHE"]=>
string(7) "54.6200" refcount(1)
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
PHP 通常更喜欢在数学运算中将对象转换为整数。假设您这样做:
此运算符的实现看到一个对象,并且必须决定如何处理它。内部对象提供了一个钩子,允许它们转换为任何类型(
cast_object
)。但是,该处理程序仅接收一种目标类型。引擎必须在执行此操作之前决定将对象转换为哪种类型,不幸的是,它选择了整数类型。您唯一的选择是像您一样添加显式强制转换。
PHP generally prefers to convert an object to a integer in the context of a mathematical operation. Let's say you do:
The implementation of this operator sees an object and has to decide what to do with it. Internal objects are provided with a hook that allows them to be converted to any type (
cast_object
). However, this handler receives only one target type. The engine has to decide to which type to convert the object before doing so, and unfortunately, it chooses the integer type.Your only option is to add an explicit cast, as you do.