在PHP中扩展DOMElement时,不会调用子类的构造函数.就预期的行为而言,没有什么能在文档中跳出来,但也许我错过了一些东西.这是一个简单的测试用例....
class SillyTestClass extends DOMElement{ public $foo=null; public function __construct($name,$value=null,$namespace=null){ echo "calling custom construct...."; $this->foo="bar"; parent::__construct($name,$value,$namespace); } public function sayHello(){ echo "Why, hello there!"; } } $doc=new DOMDocument(); $doc->registerNodeClass('DOMElement','SillyTestClass'); $doc->loadHTML(""); //THIS WORKS! CUSTOM CLASS BEING USED $doc->documentElement->firstChild->sayHello(); //THIS IS STILL NULL:( Never set by construct, no message saying construct was called either echo $doc->documentElement->firstChild->foo;Sample
当然,如果我自己实例化,那很好......
$elm=new SillyTestClass("foo","Hi there"); //WORKS! Outputs "bar"; echo $elm->foo;
为什么当我用DOMDocument注册节点类时,它不会调用__construct
偶数虽然它以其他方式给我正确的继承?
更新对于真正好奇的人或知道C的人
================================================== ===================== 调查......
这是从github上的PHP src获取的DOM扩展源代码
如果你要创建一个元素,这就是发生的事件链::
document.c :: dom_document_create_element | //uses libxml to generate a new DOMNode | node = xmlNewDocNode(docp, NULL, (xmlChar *) name, (xmlChar *) value); // that node is then sent to php_dom.c :: php_dom_create_object | | //the node type is used to figure out what extension class to use | switch (obj->type) {... | | //that class is used to instance an object | if (domobj && domobj->document) { | ce = dom_get_doc_classmap(domobj->document, ce); | } object_init_ex(return_value, ce);
看来你没有从扩展DOMNode获得真正的继承,或者如果DOMDocument实例化它们,它就是内置的扩展类(DOMElement,DOMText).在这种情况下,首先创建libxml节点,然后在第二个节点上添加类属性.
这是不幸的,似乎不可能绕过它,因为即使将importNode导入文档,它也会实例化一个新节点.例
class extendsDE extends DOMElement{ public $constructWasCalled=false; public function __construct($name){ parent::__construct($name); $this->constructWasCalled=true; } } class extendsDD extends DOMDocument{ public function __construct(){ parent::__construct(); $this->registerNodeClass("DOMElement","extendsDE"); } //@override public function createElement($name){ $elm=new extendsDE($name); echo "Element construct called when we create="; echo $elm->constructWasCalled?"true":"false"; return $this->importNode($elm); } } $doc=new extendsDD(); $node=$doc->createElement("div"); echo "
"; echo "But then when we import into document, a new element is created and construct called= "; echo $node->constructWasCalled?"true":"false";
现在辩论 - 这是开发人员的意图和文档是误导,或者它是一个错误和真正的继承应该发生?