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.

Reply via email to