I’ve some class with this signature (PHP 5.3):
class a {
public static function __callStatic($name) {
echo "unknown static method $name called";
}
public function foo() {
echo "instance method foo called";
}
}
It does this:
a::not_known();
// unknown static method not_known called -- CORRECT
$obj = new a();
$obj->foo();
// instance method foo called -- CORRECT
a::foo();
// instance method foo called -- WRONG
// should be: unknown static method foo called
Is there any way I can prevent the call to the instance method but use the __callStatic for unknown static methods? If I call a static method, I want a static method to run …
Edit: Why why the answer below from SergeS does not work (php 5.3.2):
class a {
public $name = "a";
function ident() {
if( !is_object( $this )) {
echo "I am STATIC class a\n";
} else {
echo "I am INSTANCE class a\n";
echo "\$this has name: $this->name\n";
}
}
}
class b {
public $name = "b";
function test() {
a::ident();
}
}
a::ident();
$a = new a();
$a->ident();
$b = new b();
$b->test();
gives the following output:
a::ident(); --> I am STATIC class a // correct
$a->ident(); --> I am INSTANCE class a // correct
$this has name: a // correct
$b->test(); --> I am INSTANCE class a // wrong! should be 'STATIC class a'
$this has name: b // wrong! $this is an instance of 'b'!
In the last call, the method ident of class a is called statically in an instance of b. And this passes the instance of b as $this to the method of a, which is obviously dead wrong!
It is during to definition of __callStatic – it will be called if method with this name is not reachable – but a::foo is (no matter it is or it is not static) – so, if you want to keep this construct, put this at beginning of foo method :
PS Edit example to make sure it will be same instance too – but this is not always corrct as answer for select static or non-stati call because if i have this hierarchy
Class A -> Class B -> Class C ( Class C implements both A and B ), if i want to call specific method from A i will write A::method ( similiar to specific method in B by calling B::method OR parent::method )