more static method fun
| From: | Rob Richards | Date: | Wed, 03 Mar 2004 01:23:27 +0000 |
| Subject: | more static method fun | ||
| Groups: | php.internals | ||
| Request: | Send a blank email to internals+get-8330@lists.php.net to get a copy of this message | ||
It is currently impossible to call a true static method from within a class method. It lets a class
method call any object method statically even when not defined as a static method. The static
method being called inherits the $this from the encapsulating object. This may not be a big deal
with userspace objects, but it is impossible to handle for internal objects.
Within the dom extension there are a few methods which can be called both statically and off an
instantiated object. Calling them statically works fine until they are called within a class method
as the function either expects this to be defined (meaning an instantiated object) or it to be null
(when it is called statically). Since within the class method, it magically inherits the this of the
object calling it, it currently crashes.
The following is an example using simplexml to illustrate the problem (simplexml's code base is
much smaller so easier to follow).
Class AClass {
function tester() {
print simplexml_element::asXML(); // segfaults as this should not be allowed to be called
statically
}
}
$test = new AClass();
$test->tester();
And before someone says that the object type should be tested using zend_parse_method_parameters as
a "workaround", it still wouldnt work correctly:
Class BClass extends simplexml_element {
function tester() {
print simplexml_element::asXML();
}
}
$test = new BClass("<root/>");
$test->tester();
This doesnt crash, but because the static call is being called from within an object which extends
simplexml_element, it would pass and act as if $this->asXML() was called, which also is
incorrect. It should be issuing the same non-static method cannot be called statically error as when
it is called outside a class. A better example of why it also would be incorrect would be using a
domdocument:
Class BClass extends domdocument {
var $newdoc = NULL;
function tester() {
$this->newdoc = domdocument::loadXML("<root/>");
}
}
$test = new BClass();
$test->loadXML("<root>abc</root>");
print $test->saveXML()."\n";
$test->tester();
var_dump($test->newdoc);
print $test->saveXML()."\n";
newdoc ends up as a boolean rather than a new document as $test is actually changed from the static
call as it believes it is being called as $test's method and not as a static method, which
should produce a new document rather than replacing the current document.