How can I get the class name from a static call in an extended PHP class?

I have two classes: Action and MyAction . The latter is declared as:

 class MyAction extends Action {/* some methods here */} 

All I need is a method in the Action class (only in it, because there will be many inherited classes, and I do not want to implement this method in all of them), which will return the class name from a static call. Here is what I am 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 variable __CLASS__ , which has the value "Action".

Is there any way to do this?

+71
inheritance oop php
03 Feb '09 at 11:04
source share
6 answers

__CLASS__ always returns the name of the class in which it was used, so it does not help much with the static method. If the method was not static, you can simply use get_class ($ this). eg.

 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 allow you to allow the target class to call the static method at run time and not when it is defined.

Until the function introduces a new magic constant to tell you the name of the class you were called with, it provides a new function get_called_class () , which can tell you the name of the class to which the static method was called. Here is an example:

 Class Action { public static function n() { return get_called_class(); } } class MyAction extends Action { } echo MyAction::n(); //displays MyAction 
+150
Feb 03 '09 at 11:16
source share
β€” -

Starting with version 5.5, you can use the class keyword to resolve the class name , which would be much 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 
+25
Sep 05 '14 at 22:28
source share

This is not an ideal solution, but it works on PHP <5.3.0.

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(); } } 
+15
Oct 09 '09 at 6:07
source share

Now (when 5.3 arrived) it's pretty simple:

http://ua.php.net/manual/en/function.get-called-class.php

+12
Sep 27 '09 at 12:36
source share
 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(); 
+2
Feb 14 '11 at 20:16
source share

There is no way in available versions of PHP to do what you want. Paul Dixon's solution is the only one. I mean, the example code is because the late static bindings feature he talks about is available in PHP 5.3, which is in beta.

0
03 Feb '09 at 11:27
source share



All Articles