PHP DOMDocument在克隆/返回时更改节点类实例?
我设法使用PHPDOM实现来创建包含PHP DOMDocument在克隆/返回时更改节点类实例?,php,xml,dom,Php,Xml,Dom,我设法使用PHPDOM实现来创建包含DomeElements子类的自定义文档树,但我发现了一件非常奇怪的事情:克隆或返回DOMDocument似乎会改变子节点类 基本示例 class Section extends DOMElement { public function __construct($name, $value = null, $uri = null) { parent::__construct($name, $value, $uri); } } class P
DomeElement
s子类的自定义文档树,但我发现了一件非常奇怪的事情:克隆或返回DOMDocument似乎会改变子节点类
基本示例
class Section extends DOMElement
{
public function __construct($name, $value = null, $uri = null)
{
parent::__construct($name, $value, $uri);
}
}
class Paragraph extends DOMElement
{
public function __construct($name, $value = null, $uri = null)
{
parent::__construct($name, $value, $uri);
}
}
function display_doc($label, DOMDocument $doc)
{
$endl = (PHP_SAPI == "cli") ? "\n" : "<br />";
$pad = (PHP_SAPI == "cli") ? "\t" : "&nbsp;&nbsp;";
echo ($label . $endl);
$root = $doc->documentElement;
echo ($pad . "root " . get_class($root) . $endl);
echo ($pad . "first child " . get_class($root->firstChild) . $endl);
}
function test_dom($name, DOMDocument &$instance = null)
{
$doc = ($instance) ? $instance : new DOMDocument("1.0", "utf-8");
$root = $doc->appendChild($doc->createElement("root"));
$section = new Section("section");
$root->appendChild($section);
$paragraph = new Paragraph("para");
$section->appendChild($paragraph);
$clone = clone $doc;
display_doc($name . " - Inside function", $doc);
display_doc($name . " - Inside function (clone)", $clone);
return $doc;
}
$doc = test_dom("Using new instance");
display_doc("Returned doc in global scope", $doc);
$doc2 = new DOMDocument("1.0", "utf-8");
test_dom("Using global scope instance", $doc2);
display_doc("Modified doc in global scope", $doc2);
将输出
Using new instance - Inside function
root DOMElement
first child Section
Using new instance - Inside function (clone)
root DOMElement
first child DOMElement
Returned doc in global scope
root DOMElement
first child DOMElement
Using global scope instance - Inside function
root DOMElement
first child Section
Using global scope instance - Inside function (clone)
root DOMElement
first child DOMElement
Modified doc in global scope
root DOMElement
first child DOMElement
使用新实例-内部函数
根穹隆
第一儿童组
使用新实例-内部函数(克隆)
根穹隆
第一个孩子
全局范围内返回的单据
根穹隆
第一个孩子
使用全局作用域实例-内部函数
根穹隆
第一儿童组
使用全局作用域实例-内部函数(克隆)
根穹隆
第一个孩子
在全局范围内修改单据
根穹隆
第一个孩子
当文档被克隆或返回(甚至通过引用)时,第一个子元素的类从节更改为简单的doElement
- 我的PHP版本是5.3.10,但在5.4下也会出现相同的行为
- 使用DOMDocument::registerNodeClass将通过注册的节点类转换
DomeElement
,但我有多个子类DomeElement
我的问题并不是要找到一个解决方法或不同的解决方案,但我想了解这里发生了什么,以及子节点通过什么机制进行转换
编辑:我发现了一个与此问题相关的错误报告(2年):。
建议的解决方法工作得很好,但仍然不清楚这是真正的bug还是DOM API的无效使用。当您使用新段落
和新节
时,您需要将它们存储在单独的数组中以将它们保存在内存中,这样DOMDocument
就不仅仅使用它的默认类
错误报告是准确的,我认为PHP中的DOM
的整个实现是有缺陷的
将对象的副本保存在别处是内存密集型的,不管怎样使用DOM也是如此。由于存在许多缺陷,我个人正在努力使一个像样的实现正常工作,所以你不是唯一一个:)