我想说我想将一个div附加到DOMDocument。我可以这样做:
<?php
$dom = new DOMDocument();
$dom->appendChild(
$dom->createElement("div")
);
现在,说我想在该div中添加一些文字,所以我尝试:
<?php
$dom = new DOMDocument();
$dom->appendChild(
$dom->createElement("div")
->appendChild( $dom->createTextNode("foobar") )
);
但是等等!现在有一个问题!
在第一种情况下,$dom->createElement("div")
返回一个空的&#34; div&#34; DOMNode,appendChild()接受没有问题。
但在第二种情况下,$dom->createElement("div")->appendChild($dom->createTextNode("foobar"))
会返回已经附加的&#34; foobar&#34;一个DOMText。所以&#34; div&#34; DOMNode没有被追加,并且php会发出警告。
Warning: DOMNode::appendChild(): Couldn't fetch DOMText
我的问题是,有没有办法让方法链返回原始修改的(附加了DOMText)DOMEode,由createElement()返回?
我知道我可以将DOMNode保存到变量然后将其传递给appendChild(),但我真的很想看到一个单线解决方案。
感谢。
答案 0 :(得分:1)
如果您使用PHP 5.6+,则可以使用spread / splat运算符(...
)与魔术方法__call
结合使用来修补类以满足您的需求。
基本上,您创建两个模仿DOMDocument
和DOMNode
行为的代理类,称为DOMDocumentPlus
和DOMNodePlus
。每个班级都包含一个指向真实班级的私人链接,并且通过使用魔术方法__call
,我们可以将几乎所有调用委托给原始班级&#39;方法。然后,当您在appendChild
元素上调用DOMNodePlus
时,您将返回$this
而不是孩子。
DOMDocumentPlus
课程
class DOMDocumentPlus {
private $dom;
public function __construct(...$args) {
$this->dom = new DOMDocument(...$args);
}
public function __call($name, $args) {
if($name !== 'createElement') {
return $this->dom->$name(...$args);
} else {
return new DOMNodePlus($this->dom->createElement(...$args));
}
}
}
DOMNodePlus
课程
class DOMNodePlus {
private $node;
public function __construct($node) {
$this->node = $node;
}
public function __call($name, $args) {
if($name !== 'appendChild') {
return $this->node->$name(...$args);
} else {
$this->node->appendChild(...$args);
return $this->node;
}
}
}
主程序
$dom = new DOMDocumentPlus();
$dom->appendChild(
$dom->createElement("div")->appendChild($dom->createTextNode("foobar"))
);
$dom->formatOutput = true;
echo $dom->saveHTML();
答案 1 :(得分:1)
是的,首先附加div
:
$dom = new DOMDocument();
$dom
->appendChild(
$dom->createElement("div")
)
->appendChild(
$dom->createTextNode("foobar")
);
echo $dom->saveXml();
输出:
<?xml version="1.0"?>
<div>foobar</div>
您可以使用$parentNode
属性再次向上移动。
$dom = new DOMDocument();
$dom
->appendChild(
$dom->createElement("div")
)
->appendChild(
$dom->createTextNode("foobar")
)
->parentNode
->appendChild(
$dom->createElement("span")
)
->appendChild(
$dom->createTextNode("FOOBAR")
);
echo $dom->saveXml();
输出:
<?xml version="1.0"?>
<div>foobar<span>FOOBAR</span></div>
但不要过度使用它。像这样的长链不易维护。