PHP-我可以获取对象而不是方法返回吗?
假设我想向DOMDocument追加一个div。我可以这样做:PHP-我可以获取对象而不是方法返回吗?,php,domdocument,php-5.5,Php,Domdocument,Php 5.5,假设我想向DOMDocument追加一个div。我可以这样做: <?php $dom = new DOMDocument(); $dom->appendChild( $dom->createElement("div") ); 我的问题是,有没有一种方法可以让方法链返回createElement()返回的原始修改(添加了DOMText)DOMNode 我知道我可以将DOMNode保存到一个变量中,然后将其传递给appendChild(),但我真的很想看到一个单行解决方
<?php
$dom = new DOMDocument();
$dom->appendChild(
$dom->createElement("div")
);
我的问题是,有没有一种方法可以让方法链返回createElement()返回的原始修改(添加了DOMText)DOMNode
我知道我可以将DOMNode保存到一个变量中,然后将其传递给appendChild(),但我真的很想看到一个单行解决方案
谢谢
Fiddle:如果您有PHP5.6+,您可以使用spread/splat操作符(
..
)结合magic方法\u call
对类进行猴子补丁,以满足您的需要
基本上,您可以创建两个代理类,它们模拟DOMDocument
和DOMNode
的行为,称为DOMDocumentPlus
和DOMNodePlus
。每个类都有一个到真实类的私有链接,通过使用magic方法\u call
,我们可以将几乎所有调用委托给原始类的方法。然后,当对DOMNodePlus
元素调用appendChild
时,返回$this
而不是子元素
DOMDocumentPlus
class
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));
}
}
}
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;
}
}
}
DOMNodePlus
class
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));
}
}
}
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();
是,首先附加
div
:
$dom = new DOMDocument();
$dom
->appendChild(
$dom->createElement("div")
)
->appendChild(
$dom->createTextNode("foobar")
);
echo $dom->saveXml();
输出:
<?xml version="1.0"?>
<div>foobar</div>
输出:
<?xml version="1.0"?>
<div>foobar<span>FOOBAR</span></div>
福巴福巴
但不要过度使用它。这样的长链不容易维护。您可以使用
$dom->createElement('div','foobar')
它不完全相同,但是createElement('div','foobar')
将使用给定的文本创建一个元素。或者使用html\u entities()
@Nikita240有什么问题?输出看起来是正确的。@Nikita240就我所知不正确DOMNode::appendChild()
返回添加的节点,因此您可以使用额外的变量并使用DomDocument::createTextNode()
,或者使用带有htmlentities()
的oneliner。一个可以执行类似操作的库的现成版本是FluentDOM—这里不需要代理类,您可以扩展现有的DOMDocument(并注册扩展的节点类)。但您不应该实现与DOM标准冲突的行为。FluentDOM既扩展了DOM,又有用于XML创建的特殊类。
<?xml version="1.0"?>
<div>foobar<span>FOOBAR</span></div>