在DocumentFragment中返回元素失败,因为节点不再存在


Returning element within DocumentFragment fails, because node no longer exists

这是一个突出显示我遇到的错误的测试用例。我认为节点正在被销毁/垃圾收集/函数返回后的东西-有更好的方法我可以这样做吗?

function render($doc) {
    $fragment = $doc -> createDocumentFragment();
    $fragment -> appendXML('<iframe foo="bar"/>');
    return $fragment -> childNodes -> item(0);
}
$doc = new 'DOMDocument();
$element = render($doc);
// Exception: Couldn't fetch DOMElement. Node no longer exists
echo $element -> tagName; // fails -- because element no longer exists

因为您只创建一个元素,所以不需要创建片段。只需创建元素并设置其属性。

function render($doc) {
    $element = $doc -> createElement('iframe');
    $element -> setAttribute('foo', 'bar');
    return element;
}
$doc = new DOMDocument();
$element = render($doc);
echo $element -> tagName;

我找到了一个解决方法:只需调用cloneNode()并返回克隆:

return $element->cloneNode();

我同意这是奇怪的行为…我不明白PHP为什么这样做,但至少有一个解决方法,仍然允许您使用文档片段。对于更复杂的片段,您可能需要将true传递给cloneNode以告诉它进行深度复制,我不确定。