为什么 SimpleXML 对象的计算结果为布尔值 TRUE?

问题描述 投票:0回答:3

我是 PHP 和 SimpleXMl 的新手。

我不希望在这些测试中出现错误。

  $xml=new SimpleXMLElement('<a><b>123</b></a>');
  var_dump($xml);
  echo $xml ? "true": "false";

  $xml=new SimpleXMLElement('<a><b></b></a>');
  var_dump($xml);
  echo $xml ? "true": "false";

然而,即使返回 XMLSimpleElement 对象,第二个也会返回 false。 我对到处都有命名空间的 xml 文档也有同样的问题。

这意味着我无法测试失败的 XML 解析

if (!xml)
返回 false

但是

$xml->childen($namespace)
没有。

请指教 TIA 以法莲

php simplexml
3个回答
1
投票

我无法重现您的问题,但我会尝试提供一些提示。

首先,这是将对象转换为布尔值时的规则

转换为布尔值时,将考虑以下值

FALSE

[...] 特殊类型 NULL(包括未设置的变量)
[...] 从空创建的 SimpleXML 对象 标签

所有其他值均被视为 TRUE(包括任何资源)。

其次,SimpleXMLElement 构造函数 始终返回一个对象,但它可能会引发警告和异常。

所以这些是可能性:

// Casts as TRUE because it's an object
$xml=new SimpleXMLElement('<a><b>123</b></a>');
var_dump($xml, (bool)$xml);
unset($xml);

// Casts as FALSE because it's an SimpleXMLElement object for an empty tag
$xml=new SimpleXMLElement('<a />');
var_dump($xml, (bool)$xml);
unset($xml);

// Casts as FALSE because the $xml variable was never set sucessfully so it's not even set
try{
    $xml=new SimpleXMLElement('');
}catch(Exception $e){
}
var_dump($xml, (bool)$xml); // Notice: Undefined variable: xml
unset($xml);

1
投票

PHP (5+) 中的对象评估为

TRUE
always

one例外是从空标签创建的

SimpleXML
对象 - 请参阅http://php.net/manual/en/language.types.boolean.php

$xml = new SimpleXMLElement('<b></b>');

符合这样的

FALSE
SimpleXML
对象 (
FALSE === (bool) $xml;
)。

但是

$xml = new SimpleXMLElement('');

抛出异常,如果未捕获,将停止您的程序。如果被抓住,则

$xml
不会被设置。

为什么 SimpleXML 对象的计算结果为布尔值 TRUE(或更具体地说,为布尔值 FALSE)?

这是实现定义的。 PHP 扩展可以告诉我们当对象被转换时会发生什么。例如

(bool) $xml
表示布尔值(
false
true
)或
(string) $xml
表示字符串值,而
simplexml
扩展已实现此功能。

虽然始终可以进行

bool
的强制转换,但非 stringable 对象会因
string
强制转换而失败。
SimpleXMLElement
已实现对
bool
以及
string
(以及更原始的类型,如
int
)的转换:

$xml = new SimpleXMLElement('<b></b>');

var_dump((bool)$xml);    # bool(false)
var_dump((string)$xml);  # string(0) ""

鉴于您的第二个示例,3v4l.org 显示 PHP 5.0.0-5、5.1.0-1 将

new SimpleXMLElement('<a><b></b></a>')
转换为
bool(false)
string(0) ""
以及更高版本和更当前的 PHP 版本到
bool(true)
string(0) ""

正如您在问题中所描述的,第二个示例“返回

false
,这意味着
$xml
在非严格测试时评估为 false。

但是,即使返回 XMLSimpleElement 对象,第二个也会返回 false。

这表明您的观察结果属于旧 PHP 版本的时间,然后针对第二个示例的具体情况更改了实现(参见 Bug #35028)。

从更广泛的角度来看,似乎有一段时间,空对象实际上通过

false
通过
ZEND_BOOL_NOT_SPEC_CV_HANDLER
评估为
convert_to_boolean
,同时它们也通过
true
通过
ZEND_BOOL_SPEC_CV_HANDLER
评估为
i_zend_is_true
(参见 Bug) #34199).

对于这个特定的 SimpleXML 问题来说,这似乎特别有趣,因为它可能会在

new SimpleXMLElement('<empty/>')
计算结果为 false 时提出一个基本原理。

因此,任何对象都可以通过对齐两个结构来测试错误(通过

!
):
!((object)null)
!((array)null)

这是很久以前的事了,我的理解是,这源于 Zend Engine 2 之前的时代,甚至可能是很久以前的事了。

更多最新信息:

  • 在评估期间完成布尔值转换
  • 它利用
    bool
    的转换来实现
    SimpleXMLElement
  • (如文档所述)
    false
    用于空 XML 元素

它仍然是唯一的例外,区分节点值的空字符串

""
或字符串
"0"
非常有用。


0
投票

您可以在 http://www.php.net/manual/en/language.types.boolean.php 上找到所有计算结果为 true/false 的内容(查找“当转换为布尔值时,以下值被视为 FALSE: ”)

创建SimpleXMLElement对象如果失败将会抛出异常。以下代码应该可以满足您的需要:

try
{
    $xml=new SimpleXMLElement('');
    var_dump($xml);
    echo 'true';
}
catch
{
    echo 'false';
}

要评估为真/假,您可能需要查看 ===,以显式评估为假。

$test = '';
echo $test ? 'true' : 'false'; // will output false
echo $test !== false ? 'true' : 'false'; // will output true
© www.soinside.com 2019 - 2024. All rights reserved.