How can I get the classname from a static call in an extended PHP class?
Solution 1
__CLASS__
always returns the name of the class in which it was used, so it's not much help with a static method. If the method wasn't static you could simply use get_class($this). e.g.
class Action {
public function n(){
echo get_class($this);
}
}
class MyAction extends Action {
}
$foo=new MyAction;
$foo->n(); //displays 'MyAction'
Late static bindings, available in PHP 5.3+
Now that PHP 5.3 is released, you can use late static bindings, which let you resolve the target class for a static method call at runtime rather than when it is defined.
While the feature does not introduce a new magic constant to tell you the classname you were called through, it does provide a new function, get_called_class() which can tell you the name of the class a static method was called in. Here's an example:
Class Action {
public static function n() {
return get_called_class();
}
}
class MyAction extends Action {
}
echo MyAction::n(); //displays MyAction
Solution 2
Since 5.5 you can use class
keyword for the class name resolution, which would be a lot faster than making function calls. Also works with interfaces.
// C extends B extends A
static::class // MyNamespace\ClassC when run in A
self::class // MyNamespace\ClassA when run in A
parent::class // MyNamespace\ClassB when run in C
MyClass::class // MyNamespace\MyClass
Solution 3
It's not the ideal solution, but it works on PHP < 5.3.0.
The code was copied from septuro.com
if(!function_exists('get_called_class')) {
class class_tools {
static $i = 0;
static $fl = null;
static function get_called_class() {
$bt = debug_backtrace();
if (self::$fl == $bt[2]['file'].$bt[2]['line']) {
self::$i++;
} else {
self::$i = 0;
self::$fl = $bt[2]['file'].$bt[2]['line'];
}
$lines = file($bt[2]['file']);
preg_match_all('/([a-zA-Z0-9\_]+)::'.$bt[2]['function'].'/',
$lines[$bt[2]['line']-1],
$matches);
return $matches[1][self::$i];
}
}
function get_called_class() {
return class_tools::get_called_class();
}
}
Solution 4
Now (when 5.3 has arrived) it's pretty simple:
http://php.net/manual/en/function.get-called-class.php
Solution 5
class MainSingleton {
private static $instances = array();
private static function get_called_class() {
$t = debug_backtrace();
return $t[count($t)-1]["class"];
}
public static function getInstance() {
$class = self::get_called_class();
if(!isset(self::$instances[$class]) ) {
self::$instances[$class] = new $class;
}
return self::$instances[$class];
}
}
class Singleton extends MainSingleton {
public static function getInstance()
{
return parent::getInstance();
}
protected function __construct() {
echo "A". PHP_EOL;
}
protected function __clone() {}
public function test() {
echo " * test called * ";
}
}
Singleton::getInstance()->test();
Singleton::getInstance()->test();
Comments
-
Anton over 3 years
I have two classes:
Action
andMyAction
. The latter is declared as:class MyAction extends Action {/* some methods here */}
All I need is method in the
Action
class (only in it, because there will be a lot of inherited classes, and I don’t want to implement this method in all of them), which will return classname from a static call. Here is what I’m talking about:Class Action { function n(){/* something */} }
And when I call it:
MyAction::n(); // it should return "MyAction"
But each declaration in the parent class has access only to the parent class
__CLASS__
variable, which has the value “Action”.Is there any possible way to do this?
-
user5880801 over 15 yearsThe only problem for the OP is that the feature is not yet available. PHP 5.3 is yet in beta.
-
Marecky over 11 years@Paul, thanks! You just saved my day... or night with
get_called_class()
:) -
Ian Bytchek over 9 yearsNow (when 5.5 has arrived (a long time ago)) it's even simpler: stackoverflow.com/a/25694818/458356
-
Stphane over 7 yearsI wish someone could help me with a similar issue. PHP script dies silently upon executing
new static();
from inside a private static method (using xampp on windows and php>5.5).:s
-
sammry almost 6 years$foo=new MyAction; echo get_class($foo); This also prints MyAction.
-
Alexander Kucheryuk over 3 years
get_class
and::class
may return different results (case sensitivity). Details are here - stackoverflow.com/questions/34118725/… -
Mahdi about 3 yearsuse
static::class