17

What is the difference between forward_static_call and call_user_func

And the same question applies to forward_static_call_array and call_user_func_array

Petah
  • 45,477
  • 28
  • 157
  • 213

1 Answers1

15

The difference is just that forward_static_call does not reset the "called class" information if going up the class hierarchy and explicitly naming a class, whereas call_user_func resets the information in those circumstances (but still does not reset it if using parent, static or self).

Example:

<?php
class A {
    static function bar() { echo get_called_class(), "\n"; }
}
class B extends A {
    static function foo() {
        parent::bar(); //forwards static info, 'B'
        call_user_func('parent::bar'); //forwarding, 'B'
        call_user_func('static::bar'); //forwarding, 'B'
        call_user_func('A::bar'); //non-forwarding, 'A'
        forward_static_call('parent::bar'); //forwarding, 'B'
        forward_static_call('A::bar'); //forwarding, 'B'
    }
}
B::foo();

Note that forward_static_call refuses to forward if going down the class hierarchy:

<?php
class A {
    static function foo() {
        forward_static_call('B::bar'); //non-forwarding, 'B'
    }
}
class B extends A {
    static function bar() { echo get_called_class(), "\n"; }
}
A::foo();

Finally, note that forward_static_call can only be called from within a class method.

Artefacto
  • 96,375
  • 17
  • 202
  • 225
  • +1 from the horse's mouth. *`I've been a PHP developer since late 2010`*. – alex Feb 21 '11 at 02:07
  • 1
    There's another thing worth mentioning, if the method `B::foo()` isn't static, then all calls to `A::bar()` will output `B`. Try it. Instantiate an object `$b = new B()` and call `$b->foo()`. Then make the method non-static and run the program again. – f.ardelian Mar 10 '12 at 20:40