When extending a DOMElement in PHP, the constructor of the child class is not called. Nothing jumped out of me in the docs as far as expected, but maybe I missed something. Here is a simple test case ....
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("<div><h1>Sample</h1></div>");
Of course, if I create it myself, that's fine ...
$elm=new SillyTestClass("foo","Hi there"); //WORKS! Outputs "bar"; echo $elm->foo;
Why, when I register a node class with a DOMDocument, it does not call __construct , although it gives me the correct inheritance in any other way?
UPDATE For really curious people or people who know C
============================================= ====== ====================== Research ....
This is the DOM extension source taken from PHP src on github
If you were to create an element, this is a chain of events that occur:
document.c :: dom_document_create_element |
It looks like you DO NOT get true inheritance from the DOMNode extension or it is built in extension classes (DOMElement, DOMText) if DOMDocument calls them. In this case, the libxml node is created first, and our class properties are bound to the second.
This is unfortunate and it is impossible to get around this because even when you import a Node into a document, it introduces a new node. Example
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 "<br/>"; echo "But then when we import into document, a new element is created and construct called= "; echo $node->constructWasCalled?"true":"false";
Now the discussion is what the developers intended, and the documentation is misleading, or was it supposed to be a mistake and true inheritance?