I have a base class with a static function. But I would like to have a way to know the actual class (could be the base class or a derived class) within whose context I am calling the static function.

For example:

<?php

class Foo
{
    static function Test() 
    { 
        $c = self::class;
        echo "Hello, I am creating a new instance of type $c";
        return new $c;
    }
}

class Bar extends Foo 
{
    public $someProperty;
}

$b = Bar::Test(); // This should do something different than Foo::Test();

?>

Note that the self::class in the Test() function always results in 'Foo' even if I'm calling it using the Bar:: context.

I understand I could override the Test() function in Bar but that's not what I want, I want to keep the implemented functionality in the base Test() function. But just with the actual static class context that I'm calling it with.

Is there a way for the above Test() function to say "I am creating a new instance of type Bar" and return a Bar instance, rather than a Foo ?

1

There are 1 best solutions below

3
Dale On BEST ANSWER

Let me introduced you to late static binding.

Consider the following code, it's not exactly like yours but it highlight's the issue I believe you are facing.

<?php

class A 
{

    public static $string = 'I am from class A';

    public static function getString()
    {
        return self::$string;
    }
}

class B extends A
{
    public static $string = 'I am from class B';
}

B::getString(); // returns 'I am from class A' ???!
?>

To get around this you can use late static binding to use the variable at run time context (rather than at compile time context)

<?php

class A 
{

    public static $string = 'I am from class A';

    public static function getString()
    {
        return static::$string; // note the change here
    }
}

class B extends A
{
    public static $string = 'I am from class B';
}

B::getString(); // returns 'I am from class B' and all is well 
?>

Far more information than I can give you is available here: https://www.php.net/manual/en/language.oop5.late-static-bindings.php