get_called_class or new static?

6

I do not remember which library in PHP I saw this, but there was a code snippet where, to get a new instance of the current class, the get_called_class function was used.

However PHP has the keyword static , which refers to late static binding.

It seems that the use of both produces the same result.

See:

class Yea
{
    public static function withStatic()
    {
        return new static;
    }

    public static function withCalledClass()
    {
        $class = get_called_class();
        return new $class;
    }
}


var_dump(Yea::withStatic());
var_dump(Yea::withCalledClass());

Since the output is the same, why do some prefer to use get_called_class , instead of static ?

IDEONE

    
asked by anonymous 03.10.2015 / 18:58

2 answers

3

It's worth mentioning that the get_called_class function came to exist from PHP's 5.3 version.

In addition to the difference in performances as quoted by Rafael

class Foo {
    public static function bar()
    {
        echo "\n get_called_class: ";
        $time = microtime(true);
        echo get_called_class(). ' ';
        printf('%f', microtime(true) - $time);

        echo "\n static: ";
        $time = microtime(true);
        echo static::class . ' ';
        printf('%f', microtime(true) - $time);
    }
}

echo "<pre>";
Foo::bar();
     

Result:

get_called_class: Bar 0.000006

static: Bar 0.000001

There is another question that needs to be raised. get_called_class is used in partnership with late static binding in frameworks. For example, when a framework seeks to use a service locator / IoC system, they usually use get_called_class because as this function returns the class name and this can be used to check if there are already instances together with the use of FactoryPattern

Example

class Factory
{
    private static $_instances = array();

    public static function getInstance()
    {
        $class = get_called_class();
        if (!isset(self::$_instances[$class])) {
            self::$_instances[$class] = new $class();
        }
        return self::$_instances[$class];
    }
}

class ClassExtendFactory extends Factory {}

$class = ClassExtendFactory::getInstance();
$otherClass = ClassExtendFactory::getInstance();
var_dump($class === $otherClass);
// result true { ou seja, representam o mesmo objeto, duas variáveis apontando para o mesmo endereço de alocamento da memória }

When they do not use the factory, they only use late static binding

abstract class AbstractExample {
    public static function getInstance() {
        return new static();
    }
}

class Example extends AbstractExample {

}

$ex1 = Example::getInstance();
$ex2 = Example::getInstance();
var_dump($ex1 === $ex2);
// return false { ou seja, agora são 2 instâncias diferentes da mesma class, duas variáveis apontando para espaços diferentes de alocamento na memória }

That's it, I hope it helped you understand a little better.

    
27.10.2015 / 13:14
5

The function get_called_class() returns the name of the class, while static returns the class itself.

From PHP 5.5, you can also use static::class to return the class name.

I think it's more a style issue, but I'd recommend using static (especially if your goal is to instantiate the class, as in your example), for two reasons:

  • 1) It's shorter, your code gets cleaner;
  • 2) Performance. Although almost imperceptible, any function call has costs.

You can make a simple comparison, like this:

class Foo {
    public static function bar()
    {
        echo "\n get_called_class: ";
        $time = microtime(true);
        echo get_called_class(). ' ';
        printf('%f', microtime(true) - $time);

        echo "\n static: ";
        $time = microtime(true);
        echo static::class . ' ';
        printf('%f', microtime(true) - $time);
    }
}

echo "<pre>";
Foo::bar();

Result:

  

get_called_class: Bar 0.000006

     

static: Bar 0.000001

These times may vary slightly on each page load.

    
22.10.2015 / 20:32