geckob
geckob

Reputation: 8130

Why __call is being invoked instead of __callStatic

I tried to refer this question on SO, but still don't get it.

<?php

class A {
    public function __call($method, $parameters) {
        echo "I'm the __call() magic method".PHP_EOL;
    }

    public static function __callStatic($method, $parameters) {
        echo "I'm the __callStatic() magic method".PHP_EOL;
    }
}

class B extends A {
    public function bar() {
        A::foo();
    }

    public function foo() {
        parent::foo();
    }
}

(new B)->bar();
(new B)->foo();

From what I understand, the bar function is calling the foo method on class A statically but the foo method call the method using the instance of A which is the parent of B. I am expecting it should gives me:

I'm the __callStatic() magic method
I'm the __call() magic method

But, apparently, I get:

I'm the __call() magic method
I'm the __call() magic method

Upvotes: 4

Views: 134

Answers (2)

Timurib
Timurib

Reputation: 2743

From relevant issue:

...A::foo() is not necessarily a static call. Namely, if foo() is not static and there is a compatible context ($this exists and its class is either the class of the target method or a subclass of it), an instance call will be made.

If foo() is static it works as you expect:

class A {
    public function __call($method, $parameters) {
        echo "I'm the __call() magic method $method".PHP_EOL;
    }

    public static function __callStatic($method, $parameters) {
        echo "I'm the __callStatic() magic method $method".PHP_EOL;
    }
}

class B extends A {
    public static function foo() { // <-- static method
        parent::foo();
    }
}

(new B)->foo();

I'm the __callStatic() magic method foo

Upvotes: 3

Federkun
Federkun

Reputation: 36924

A::foo(), depending on the context, is not always a static call. Since inside B::bar() the $this object exists, and there isn't a static method named foo declared in A, and B is a subclass of A, then an instance call will be made, therefore the __call magic method will be invoked. When any of these conditions is not met, a static call will be made instead.

Upvotes: 3

Related Questions