问题
Do method chaining with PHP is easy. But I need something like this,
$xml = $dom->transformToThis('file1.xsl')->transformToThis('file2.xsl')->saveXML();
or
$books = $dom->
transformToThis('file1.xsl')->
transformToThis('file2.xsl')->
getElementsByTagName('book');
It is possible with PHP's DOMDocument or DOMNode?
class DOMxx extends DOMDocument {
public function __construct() {
parent::__construct("1.0", "UTF-8");
}
function trasformToThis($xslfile) {
$xsldom = new DOMDocument('1.0', 'UTF-8');
$xsldom->load($xslfile);
$xproc = new XSLTProcessor();
$xproc->importStylesheet($xsldom);
$this = $xproc->transformToDoc($this); // ERROR!
return $this;
}
} // class
The $this = X is a invalid construct in PHP, and I not understand the workaround explained here. I can use something like $this->loadXML( $xproc->transformToDoc($this)->saveXML() ); but it is a big overload, and the question is about how to do the correct thing.
Another (wrong) way to try to implement,
function trasformToThis($xslfile) {
... same ...
return $xproc->transformToDoc($this); // lost trasformToThis() method
}
so, in this case the question is "How to cast to DOMxx?".
回答1:
How about something like this:
class DOMxx {
function __construct($version = '1.0', $encoding = 'UTF-8') {
$this->document = new DOMDocument($version, $encoding);
}
function __call($name, $args) {
$callback = array($this->document, $name);
return call_user_func_array($callback, $args);
}
function transformToThis($xslfile) {
$xsldom = new DOMDocument('1.0', 'UTF-8');
$xsldom->load($xslfile);
$xproc = new XSLTProcessor();
$xproc->importStylesheet($xsldom);
$this->document = $xproc->transformToDoc($this->document);
return $this;
}
}
Instead of extending from DOMDocument, you keep an internal reference to a DOMDocument object inside your DOMxx class. The majority of methods are just forwarded to this internal object via the __call method. And the transformToThis method just updates the reference with the new document returned from the transformToDoc call.
回答2:
Do you have a definite requirement that transformToThis() has to modify the original object? I'd think it would be cleaner to do something like this:
function trasform($xslfile) {
$xsldom = new DOMDocument('1.0', 'UTF-8');
$xsldom->load($xslfile);
$xproc = new XSLTProcessor();
$xproc->importStylesheet($xsldom);
$xml = $xproc->transformToXML($this);
$newDom = new DOMxx();
$newDom.loadXML($xml);
return $newDom;
}
If you really want to modify the original object, I imagine this would work also (for that last part of the method):
$xml = $xproc->transformToXML($this);
$this.loadXML($xml);
return $this;
来源:https://stackoverflow.com/questions/17710890/how-to-do-method-chaining-with-domdocument