Carlos2W Carlos2W - 1 year ago 120
PHP Question

PHP Get child class name from parent class differences

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() {

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


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. Consider:

class Foo {
     public static function name() { echo get_class(); }
class Bar extends Foo {
     public static function name() { echo get_class(); parent::name(); }

What should that return? Depends upon what you want, but in PHP 5.2 you only had one choice.

So, get_called_class was introduced in PHP 5.3 to resolve this 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');


 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.