PHP-我可以获取对象而不是方法返回吗?

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(),但我真的很想看到一个单行解决方

假设我想向DOMDocument追加一个div。我可以这样做:

<?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>