Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP5:在原始(父)类的对象上应用扩展类的方法_Php_Oop_Domdocument - Fatal编程技术网

PHP5:在原始(父)类的对象上应用扩展类的方法

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

我试图扩展两个原生PHP5类(DOMDocument和DOMNode),以实现两个方法(selectNodes和selectSingleNode),从而简化XPath查询。我原以为这会很难,但我陷入了一个问题,我认为这是OOP初学者的问题

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);
  }
}