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
?
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