LIBXML_NOENT 有什么作用(为什么不叫 LIBXML_ENT)?
What does LIBXML_NOENT do (and why isn't it called LIBXML_ENT)?
在 PHP 中,可以将可选参数传递给各种 XML 解析器,其中之一是 LIBXML_NOENT
。 documentation 是这样说的:
LIBXML_NOENT (integer)
Substitute entities
Substitute entities
信息量不大(什么实体?它们什么时候被替换?)。但我认为假设 NOENT
是 NO_ENTITIES
或 NO_EXTERNAL_ENTITIES
的缩写是公平的,所以对我来说,这个标志禁用(外部)实体的解析似乎是一个公平的假设。
但这确实不是情况:
$xml = '<!DOCTYPE root [<!ENTITY c PUBLIC "bar" "/etc/passwd">]>
<test>&c;</test>';
$dom = new DOMDocument();
$dom->loadXML($xml, LIBXML_NOENT);
echo $dom->textContent;
结果是回显了/etc/passwd的内容。如果没有 LIBXML_NOENT
参数,情况就不是这样了。
对于非外部实体,该标志似乎没有任何作用。示例:
$xml = '<!DOCTYPE root [<!ENTITY c "TEST">]>
<test>&c;</test>';
$dom = new DOMDocument();
$dom->loadXML($xml);
echo $dom->textContent;
此代码的结果是 "TEST",有和没有 LIBXML_NOENT
。
该标志似乎对 <
.
等预定义实体没有任何影响
所以我的问题是:
LIBXML_NOENT
标志到底有什么作用?
- 为什么叫
LIBXML_NOENT
?它的缩写是什么,LIBXML_ENT
或 LIBXML_PARSE_EXTERNAL_ENTITIES
不是更合适吗?
- 是否有一个标志实际上阻止了所有实体的解析?
问:LIBXML_NOENT 标志到底有什么作用?
该标志启用 XML 字符实体引用的替换,无论外部与否。
问:为什么叫LIBXML_NOENT?它是什么的缩写,LIBXML_ENT 或 LIBXML_PARSE_EXTERNAL_ENTITIES 不是更合适吗?
这个名字确实具有误导性。我认为 NOENT
只是意味着解析文档的节点树不包含任何实体节点,因此解析器将替换实体。如果没有 NOENT
,解析器会为实体引用创建 DOMEntityReference 个节点。
问:是否有一个标志实际上阻止了所有实体的解析?
LIBXML_NOENT
启用 all 实体引用的替换。如果您不想扩展实体,只需省略该标志即可。例如
$xml = '<!DOCTYPE test [<!ENTITY c "TEST">]>
<test>&c;</test>';
$dom = new DOMDocument();
$dom->loadXML($xml);
echo $dom->saveXML();
打印
<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY c "TEST">
]>
<test>&c;</test>
似乎 textContent
自己替换了实体,这可能是 PHP 绑定的一个特点。没有 LIBXML_NOENT
,它会导致内部和外部实体的不同行为,因为后者不会被加载。
在 PHP 中,可以将可选参数传递给各种 XML 解析器,其中之一是 LIBXML_NOENT
。 documentation 是这样说的:
LIBXML_NOENT (integer)
Substitute entities
Substitute entities
信息量不大(什么实体?它们什么时候被替换?)。但我认为假设 NOENT
是 NO_ENTITIES
或 NO_EXTERNAL_ENTITIES
的缩写是公平的,所以对我来说,这个标志禁用(外部)实体的解析似乎是一个公平的假设。
但这确实不是情况:
$xml = '<!DOCTYPE root [<!ENTITY c PUBLIC "bar" "/etc/passwd">]>
<test>&c;</test>';
$dom = new DOMDocument();
$dom->loadXML($xml, LIBXML_NOENT);
echo $dom->textContent;
结果是回显了/etc/passwd的内容。如果没有 LIBXML_NOENT
参数,情况就不是这样了。
对于非外部实体,该标志似乎没有任何作用。示例:
$xml = '<!DOCTYPE root [<!ENTITY c "TEST">]>
<test>&c;</test>';
$dom = new DOMDocument();
$dom->loadXML($xml);
echo $dom->textContent;
此代码的结果是 "TEST",有和没有 LIBXML_NOENT
。
该标志似乎对 <
.
所以我的问题是:
LIBXML_NOENT
标志到底有什么作用?- 为什么叫
LIBXML_NOENT
?它的缩写是什么,LIBXML_ENT
或LIBXML_PARSE_EXTERNAL_ENTITIES
不是更合适吗? - 是否有一个标志实际上阻止了所有实体的解析?
问:LIBXML_NOENT 标志到底有什么作用?
该标志启用 XML 字符实体引用的替换,无论外部与否。
问:为什么叫LIBXML_NOENT?它是什么的缩写,LIBXML_ENT 或 LIBXML_PARSE_EXTERNAL_ENTITIES 不是更合适吗?
这个名字确实具有误导性。我认为 NOENT
只是意味着解析文档的节点树不包含任何实体节点,因此解析器将替换实体。如果没有 NOENT
,解析器会为实体引用创建 DOMEntityReference 个节点。
问:是否有一个标志实际上阻止了所有实体的解析?
LIBXML_NOENT
启用 all 实体引用的替换。如果您不想扩展实体,只需省略该标志即可。例如
$xml = '<!DOCTYPE test [<!ENTITY c "TEST">]>
<test>&c;</test>';
$dom = new DOMDocument();
$dom->loadXML($xml);
echo $dom->saveXML();
打印
<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY c "TEST">
]>
<test>&c;</test>
似乎 textContent
自己替换了实体,这可能是 PHP 绑定的一个特点。没有 LIBXML_NOENT
,它会导致内部和外部实体的不同行为,因为后者不会被加载。