PHP5:在原始(父)类的对象上应用扩展类的方法
我试图扩展两个原生PHP5类(DOMDocument和DOMNode),以实现两个方法(selectNodes和selectSingleNode),从而简化XPath查询。我原以为这会很难,但我陷入了一个问题,我认为这是OOP初学者的问题PHP5:在原始(父)类的对象上应用扩展类的方法,php,oop,domdocument,Php,Oop,Domdocument,我试图扩展两个原生PHP5类(DOMDocument和DOMNode),以实现两个方法(selectNodes和selectSingleNode),从而简化XPath查询。我原以为这会很难,但我陷入了一个问题,我认为这是OOP初学者的问题 class nDOMDocument extends DOMDocument { public function selectNodes($xpath){ $oxpath = new DOMXPath($this); return $o
class nDOMDocument extends DOMDocument {
public function selectNodes($xpath){
$oxpath = new DOMXPath($this);
return $oxpath->query($xpath);
}
public function selectSingleNode($xpath){
return $this->selectNodes($xpath)->item(0);
}
}
然后,我尝试扩展DOMNode以实现相同的方法,以便可以直接在节点上执行XPath查询:
class nDOMNode extends DOMNode {
public function selectNodes($xpath){
$oxpath = new DOMXPath($this->ownerDocument,$this);
return $oxpath->query($xpath);
}
public function selectSingleNode($xpath){
return $this->selectNodes($xpath)->item(0);
}
}
现在,如果我(在任意XMLDocument上)执行以下代码:
第三行工作并返回DOMNode对象$node1。但是,第四行不起作用,因为selectSingleNode方法属于nDOMNode类,而不是DOMNode。
所以我的问题是:有没有办法在某个时候将返回的DOMNode对象“转换”为一个nDOMNode对象?我觉得我遗漏了一些要点,我非常感谢你的帮助
(很抱歉,这是对我问题的重申)您需要编写nDOMDocument::selectSingleNode()以返回nDOMNode对象。没有什么神奇的变化可以发生
我说你应该继续你的实验,因为你会学到一些很好的OOP课程(尽管是很难的)。这没什么问题。您需要编写nDOMDocument::selectSingleNode()以返回nDOMNode对象。没有什么神奇的变化可以发生
我说你应该继续你的实验,因为你会学到一些很好的OOP课程(尽管是很难的)。这没什么问题。我认为您可能需要在这里花很长的时间,安装指向下、上、左、右的指针属性,有点像DOM对JavaScript所做的那样。在创建结构时,必须分配这些属性。我认为您可能需要在这里花很长的时间,安装指向下、上、左、右的指针属性,有点像DOM对JavaScript所做的那样。在创建结构时,必须指定这些属性。面向对象方法的一个后果是继承是单向的。也就是说,没有办法让父母知道孩子的方法。因此,虽然您可能能够遍历对象集合,但只能可靠地调用父类的方法。PHP确实有办法在运行时测试方法是否存在,这可能很有用,但也可能很快变得丑陋 这意味着,当您扩展一个内置类时,您需要完全扩展它,以便您的应用程序永远不会使用内置类的实例——只使用您的版本。在您的情况下,需要扩展扩展类以覆盖所有返回父类类型的父类方法:
public myClass extends foo {
// override all methods that would normally return foo objects so that they
// return myClass objects.
}
面向对象方法的后果之一是继承是单向的。也就是说,没有办法让父母知道孩子的方法。因此,虽然您可能能够遍历对象集合,但只能可靠地调用父类的方法。PHP确实有办法在运行时测试方法是否存在,这可能很有用,但也可能很快变得丑陋 这意味着,当您扩展一个内置类时,您需要完全扩展它,以便您的应用程序永远不会使用内置类的实例——只使用您的版本。在您的情况下,需要扩展扩展类以覆盖所有返回父类类型的父类方法:
public myClass extends foo {
// override all methods that would normally return foo objects so that they
// return myClass objects.
}
我认为您最好在这里使用包装器对象来装饰现有的库,而不是直接对它们进行子类化。正如您已经看到的,您不能轻易地将helper方法附加到
DOMDocument
并让它返回子类对象
具体来说,这里的问题是不知道返回nDOMNode
如果尝试执行以下操作,则会失败(许多属性似乎是):
如果改为包装对象,则可以使用\uuu get()
和\uu call()
快速公开现有的DOMNode接口,并包含附加功能,并选择返回自己的包装/自定义类以实现原始目标
例如:
class nDOMNode {
protected $_node;
public function __construct(DOMNode $node) {
$this->_node = $node;
}
// your methods
}
class nDOMDocument {
protected $_doc;
public function __construct(DOMDocument $doc) {
$this->_doc = $doc;
}
...
public function selectNodes($xPath){
$oxPath = new DOMXPath($this->_doc->ownerDocument, $this->_doc);
return $oxPath->query($xPath);
}
public function selectSingleNode($xPath) {
return new nDOMNode($this->selectNodes($xPath)->item(0));
}
}
$doc = new nDOMDocument(new DOMDocument);
$doc->loadXML('<xml>');
$node = $doc->selectSingleNode("//item[@id=2]"); // returns nDOMNode
类nDOMNode{
受保护的$\u节点;
公共函数构造(DOMNode$node){
$this->_node=$node;
}
//你的方法
}
类文档{
受保护的$\u文件;
公共函数构造(DOMDocument$doc){
$this->\u doc=$doc;
}
...
公共函数selectNodes($xPath){
$oxPath=newdomXPath($this->\u doc->ownerDocument,$this->\u doc);
返回$oxPath->query($xPath);
}
公共函数selectSingleNode($xPath){
返回新的nDOMNode($this->selectNodes($xPath)->项(0));
}
}
$doc=新的nDOMDocument(新的DOMDocument);
$doc->loadXML(“”);
$node=$doc->selectSingleNode(//item[@id=2]”;//返回nDOMNode
希望这能有所帮助。我认为您最好在这里使用包装器对象装饰现有库,而不是直接将其子类化。正如您已经看到的,您不能轻易地将helper方法附加到
DOMDocument
并让它返回子类对象
具体来说,这里的问题是不知道返回nDOMNode
如果尝试执行以下操作,则会失败(许多属性似乎是):
如果改为包装对象,则可以使用\uuu get()
和\uu call()
快速公开现有的DOMNode接口,并包含附加功能,并选择返回自己的包装/自定义类以实现原始目标
例如:
class nDOMNode {
protected $_node;
public function __construct(DOMNode $node) {
$this->_node = $node;
}
// your methods
}
class nDOMDocument {
protected $_doc;
public function __construct(DOMDocument $doc) {
$this->_doc = $doc;
}
...
public function selectNodes($xPath){
$oxPath = new DOMXPath($this->_doc->ownerDocument, $this->_doc);
return $oxPath->query($xPath);
}
public function selectSingleNode($xPath) {
return new nDOMNode($this->selectNodes($xPath)->item(0));
}
}
$doc = new nDOMDocument(new DOMDocument);
$doc->loadXML('<xml>');
$node = $doc->selectSingleNode("//item[@id=2]"); // returns nDOMNode
类nDOMNode{
受保护的$\u节点;
公共函数构造(DOMNode$node){
$this->_node=$node;
}
//你的方法
}
类文档{
受保护的$\u文件;
$doc->registerNodeClass('DOMElement', 'Foo');
$doc = new nDOMDocument;
$doc->loadxml('<a><b><c>foo</c></b></a>');
$a = $doc->selectSingleNode('//a');
$c = $a->selectSingleNode('//c');
echo 'content: ', $c->textContent;
class nDOMElement extends DOMElement {
public function selectNodes($xpath){
$oxpath = new DOMXPath($this->ownerDocument);
return $oxpath->query($xpath);
}
public function selectSingleNode($xpath){
return $this->selectNodes($xpath)->item(0);
}
}
class nDOMDocument extends DOMDocument {
public function __construct($version=NULL, $encoding=NULL) {
parent::__construct($version, $encoding);
$this->registerNodeClass('DOMElement', 'nDOMElement');
}
public function selectNodes($xpath){
$oxpath = new DOMXPath($this);
return $oxpath->query($xpath);
}
public function selectSingleNode($xpath){
return $this->selectNodes($xpath)->item(0);
}
}