【发布时间】:2015-01-25 04:50:15
【问题描述】:
考虑这个 PHP 代码:
<?php
$xmlString =
'<'.'?xml version="1.0" encoding="UTF-8"?'.'>' .
'<rootEl>' .
'<a attrA="valA">xxx</a>' .
'<b attrB="valB"/>' .
'<c>oink</c>' .
'<d/>'.
'<e>' .
'<f>zzz</f>' .
'</e>' .
'</rootEl>';
$xml = simplexml_load_string( $xmlString );
foreach ( $xml->children() as $child ) {
echo "\$CHILD [" . $child->getName() . "]: " . $child->asXML();
echo "\n";
$insideIf1 = false;
if ($child) { $insideIf1 = true; }
$insideIf2 = false;
if (true == $child) { $insideIf2 = true; }
$insideIf3 = false;
if ((boolean)$child) { $insideIf3 = true; }
echo " - if(\$CHILD) return \"true\"; else return \"false\"; : " . (($insideIf1)?"true":"false")."\n";
echo " - if(true == \$CHILD) return \"true\"; else return \"false\"; : " . (($insideIf2)?"true":"false")."\n";
echo " - if((boolean)\$CHILD) return \"true\"; else return \"false\"; : " . (($insideIf3)?"true":"false")."\n";
echo " - ((\$CHILD)?\"true\":\"false\"): " . (($child)?"true":"false")."\n";
echo " - ((true == \$CHILD)?\"true\":\"false\"): " . ((true == $child)?"true":"false")."\n";
echo " - (((boolean)\$CHILD)?\"true\":\"false\"): " . (((boolean)$child)?"true":"false")."\n";
echo "\n";
}
根据 PHP 文档(在线,请参阅 http://php.net/manual/en/control-structures.if.php):
正如关于表达式的部分所述,表达式被计算 为其布尔值。如果表达式的计算结果为 TRUE,PHP 将 执行语句,如果它的计算结果为 FALSE - 它会忽略它。 有关哪些值评估为 FALSE 的更多信息,请参见 “转换为布尔值”部分。
此解释的“转换为布尔值”部分指出:
转换为布尔值 转换为布尔值时,以下值被视为 FALSE: ...遗漏...
从空标签创建的 SimpleXML 对象
如果你执行上面的代码,这些是我的 PHP 5.5.9-1ubuntu4.5 (cli) 上的结果:
$CHILD [a]: <a attrA="valA">xxx</a>
- if($CHILD) return "true"; else return "false"; : true
- if(true == $CHILD) return "true"; else return "false"; : true
- if((boolean)$CHILD) return "true"; else return "false"; : true
- (($CHILD)?"true":"false"): true
- ((true == $CHILD)?"true":"false"): true
- (((boolean)$CHILD)?"true":"false"): true
$CHILD [b]: <b attrB="valB"/>
- if($CHILD) return "true"; else return "false"; : true
- if(true == $CHILD) return "true"; else return "false"; : false
- if((boolean)$CHILD) return "true"; else return "false"; : true
- (($CHILD)?"true":"false"): true
- ((true == $CHILD)?"true":"false"): false
- (((boolean)$CHILD)?"true":"false"): true
$CHILD [c]: <c>oink</c>
- if($CHILD) return "true"; else return "false"; : false
- if(true == $CHILD) return "true"; else return "false"; : true
- if((boolean)$CHILD) return "true"; else return "false"; : false
- (($CHILD)?"true":"false"): false
- ((true == $CHILD)?"true":"false"): true
- (((boolean)$CHILD)?"true":"false"): false
$CHILD [d]: <d/>
- if($CHILD) return "true"; else return "false"; : false
- if(true == $CHILD) return "true"; else return "false"; : false
- if((boolean)$CHILD) return "true"; else return "false"; : false
- (($CHILD)?"true":"false"): false
- ((true == $CHILD)?"true":"false"): false
- (((boolean)$CHILD)?"true":"false"): false
$CHILD [e]: <e><f>zzz</f></e>
- if($CHILD) return "true"; else return "false"; : true
- if(true == $CHILD) return "true"; else return "false"; : false
- if((boolean)$CHILD) return "true"; else return "false"; : true
- (($CHILD)?"true":"false"): true
- ((true == $CHILD)?"true":"false"): false
- (((boolean)$CHILD)?"true":"false"): true
子元素“b”和“d”是空的,因此我期待“false”,而“a”、“c”、“e”不是空的,所以我期待“true”。
事实证明,PHP 文档中的声明绝对不正确,而且行为甚至看起来也不一致:隐式或显式转换为布尔值的行为方式不同(参见元素“c”的情况) ,并且如果将裸 SimpleXML 对象用作“if”条件表达式(“if”和三元运算符),则该表达式的计算结果会以某种方式从强制转换为布尔值。
有人知道这里发生了什么吗?
【问题讨论】:
-
刚刚在 PHP 中将此作为 BUG 归档:错误 #68507:SimpleXML 对象转换为布尔值不一致bugs.php.net/bug.php?id=68507
-
不太确定。你检查过对象的结构吗?
标签: php xml casting expression simplexml