我设法使用PHP DOM实现来创建包含DOMElement
子类的自定义文档树,但我发现了一些非常奇怪的东西:克隆或返回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
克隆或返回文档时,第一个孩子的班级从Section
更改为简单DOMElement
DOMElement
,但我有多个DOMElement
的子类我的问题不是找到解决方法或不同的解决方案,但我想了解这里发生了什么以及子节点转换的机制。
编辑:我发现了与此问题相关的错误报告(2年):http://www.mail-archive.com/php-bugs@lists.php.net/msg134710.html。 建议的解决方法运行良好但不清楚它是否是一个真正的错误或无效使用DOM API
答案 0 :(得分:1)
当你使用new Paragraph
和new Section
时,你需要将它们存储在一个单独的数组中,以便将它们保存在内存中,这样DOMDocument
不会只使用它的默认类。 / p>
错误报告是准确的,我认为PHP中DOM
的整个实现存在缺陷。
将对象的副本保存在别处是内存密集型的,就像使用DOM一样。由于存在许多缺陷,我正在为个人努力工作而努力工作,所以你不是唯一一个:)