1

I would like to get child class in parent class construct. The thing is, I found several PHP methods here in SO and don't know which one to use, which one is faster ?

class Parent {
    function __construct() {
        echo static::class;      // Method 1 (PHP 5.5+)
        echo get_called_class(); // Method 2 (PHP 5.3+)
        echo get_class($this);   // Method 3 (PHP 5.2+)
    }
}
class Child extends Parent {
    function __construct() {
        parent::__construct();
    }
}

All echos write same result : Child. But why there's 3 different method for same result ? Which one is better, or more optimized ?

Carlos2W
  • 2,024
  • 2
  • 16
  • 19
  • 1
    Why don't you run some performance tests to see? – Mark Baker May 20 '16 at 14:54
  • Question is not **only** about performance, but also why there's 3 method for same result, if there's other difference. – Carlos2W May 20 '16 at 14:57
  • `get_class($this)` can be called passing in instances of any object, including (but not limited to) `$this`; e.g. $x = new DateTime(); echo get_class($x);`; so `get_class()` is a very generic function that has other uses – Mark Baker May 20 '16 at 14:59

1 Answers1

4

The three different versions represent the evolution of PHP handling of static. The earliest one get_class was insufficient to handle scenarios where you needed to distinguish the class as called and the class as defined. Here is an example

So, get_called_class was introduced in PHP 5.3 to resolve the ambiguity. That lasted quite a while, and is still a valid choice, but now we have the pseudo selector ::class. Why?

The pseudo selector provides two nice benefits. The first is that it allows you to replace string class names with compile-time checking of namespace rules. Compare:

 namespace Foo\Bar;
 class Baz { public static function hi($name) { echo "Hi, $name!"; } }
 call_user_func([ Baz::class, 'hi' ], 'bishop');

with:

 call_user_func([ '\Foo\Bar\Baz', 'hi' ], 'bishop');

If I fat finger that last one, mistyping it, that will be a run-time error:

 call_user_func([ '\Foo\Bar\Bza', 'hi' ], 'bishop'); // error at runtime!

But using the ::class pseudo I get compile-time checking:

 call_user_func([ Bza::class, 'hi' ], 'bishop'); // error at compile-time!

I realize in an interpreted language the distinction between compile-time and run-time is thin, but it does matter when it comes to performance. And that's the second benefit: ::class is more performant.

Community
  • 1
  • 1
bishop
  • 37,830
  • 11
  • 104
  • 139