Jules Lamur
Jules Lamur

Reputation: 2368

Why does PHP prefer __call() to __callStatic()?

When I try this :

<?php
class myParent {
    public function __call($method, $params) {
        echo "from __call";
    }

    public function __callStatic($method, $params) {
        echo "from __callStatic";
    }
}

class mySon extends myParent {
    public function bar() {
        myParent::foo();
    }
}

(new mySon())->bar();

I expect this output : from __callStatic ...

Instead it gives : from __call.

Can someone explain me why ?


EDIT: To be exact I was wondering why if I delete the __call function, then it triggers __callStatic and if there's a way to trigger __callStatic when __call is declared.

Upvotes: 6

Views: 299

Answers (3)

Sjon
Sjon

Reputation: 5155

2 things happen here, first of all: PHP supports classname::method as an alias for parent::method, and a way to skip certain classes in the tree as demonstrated here.

Second, parent:: is not a static call, and it's impossible to statically call methods on parents, using either parent:: or classname::. I actually opened a bug report but this didn't trigger any developer into making this any better.

Both of these combined results in the non-intuitive behavior you're seeing

Upvotes: 4

Jules Lamur
Jules Lamur

Reputation: 2368

Well, I found an obvious solution for what I wanted to do :

class mySon extends myParent {
    public function bar() {
        myParent::__callStatic('foo', array());
    }
}

Upvotes: 1

Machavity
Machavity

Reputation: 31614

You called the function statically but from within an instance of the class. So PHP called the instance based __call(). Note that this code is functionally equivalent to what you wrote statically

class mySon extends myParent {
    public function bar() {
        $this->foo(); // works the same way as myParent::foo();
    }
}

If you called it like so, you'd get the static (note, __callStatic() has to be static itself)

class myParent {
    public function __call($method, $params) {
        echo "from __call";
    }

    public static function __callStatic($method, $params) {
        echo "from __callStatic";
    }
}
myParent::foo();

Upvotes: 3

Related Questions