我将如何扩展 DOMNode,从该扩展 DOMDocument 并从中创建我自己的文档扩展?
在 PHP 中,我们没有多重继承。这意味着,您尝试做的事情在 PHP 中是不可能的。原因是 DOMDocument 是从 DOMNode 扩展而来的(就像 DOMElement、DOMAttr、DOMText 等一样),所以这个继承路径已经完成(DaveRandom在他的回答中解释得更冗长,可能措辞更好,如果你想知道,我的意思是一样的)。
PHP 5.4 使情况稍微好一点,因为您可以将在所有子类型之间共享的代码(例如,您将放入DOMNode的代码)放入traits中。
然后,您创建的每个子类型都可以使用这些特征(您很快就会看到一个示例)。
如果您还想让它们都成为您的 DOMNode类型,您还可以定义一个空接口,然后使用您的所有子类型实现该接口。
以下是示例爬虫库中该技术的示例:
class ScraperDoc extends DOMDocument implements ScraperNodeType
{
use ScraperNodeTrait;
...
如图所示,它实现了一个接口 ( ScraperNodeType
) 和一个 trait ( ScraperNodeTrait
)。
于是就有了界面:
/**
* Empty Interface for typing reasons (instanceof operator and traits
* work not well, this interface cures that limitation a bit)
*/
interface ScraperNodeType
{
}
并且有特点;如果您不熟悉 trait,这里有一些示例代码,一个为实现该 trait 的所有节点提供字符串上下文的单一方法 trait(只是为了给出一个想法,它是从原始库中缩短的):
Trait ScraperNodeTrait
{
public function __toString()
{
/* @var $this DOMNode */
return trim($this->textContent);
}
}
这不像 Ruby 中的 traits/mixins 那样流畅,但在 PHP 中尽可能接近(到目前为止,使用非动态代码)。
这仍然不能解决创建自己的层次结构的所有问题,但我认为你应该了解这种技术(特征 + 空接口)。
这是一个继承图,显示了DOMNode
顶部,然后是 PHP DOM 扩展的扩展类型,然后是这些扩展的用户级扩展以及它们与 trait(左下)和接口(右下)的关系。
右侧的 cluser 与迭代器和 simplexml 相关,这不是此答案的一部分,因此没有直接兴趣。尽管它例如表明您不能DOMNodeList
在 PHP 中重载。SimpleXML 可能有一些疯狂的举动,这就是为什么该库也将它作为整个图片的一部分。
然后在左下角,您可以找到对 Net_URL2 的引用,这是迄今为止最好的 PHP URL 类,恕我直言。该库从它扩展,因此具有自己的 URL 类型,并且外部库至少分层到代码库中。
![在此处输入图像描述](https://i.stack.imgur.com/Gcm0Z.png)
基于 DOMDocument 继承图的示例抓取库(全尺寸)
我希望这会有所帮助,也能给我一些启发。上次我回答一个关于扩展 DOMDocument 的问题是关于 DOMDocument 是一个模型,而不是你的模型的现象: