如何从扩展的PHP类中的静态调用获取类名?
我有两个类: Action
和MyAction
。 后者被宣布为:
class MyAction extends Action {/* some methods here */}
我所需要的只是Action
类中的方法(仅在这个类中,因为会有很多inheritance类,而且我不想在所有这些类中实现这个方法),它将从静态调用中返回classname。 以下是我正在谈论的内容:
Class Action { function n(){/* something */} }
当我把它叫做:
MyAction::n(); // it should return "MyAction"
但是父类中的每个声明都只能访问具有值“Action”的父类__CLASS__
variables。
有没有办法做到这一点?
__CLASS__
总是返回它所使用的类的名字,所以对静态方法没有多大的帮助。 如果方法不是静态的,你可以简单地使用get_class ($ this)。 例如
class Action { public function n(){ echo get_class($this); } } class MyAction extends Action { } $foo=new MyAction; $foo->n(); //displays 'MyAction'
迟到的静态绑定,在PHP 5.3+中可用
现在PHP 5.3已经发布了,你可以使用晚期的静态绑定 ,它可以让你在运行时parsing目标类的静态方法调用,而不是定义静态方法。
虽然这个特性并没有引入一个新的魔术常量来告诉你被调用的类名,但它提供了一个新的函数get_called_class() ,它可以告诉你一个静态方法被调用的类的名字。下面是一个例子:
Class Action { public static function n() { return get_called_class(); } } class MyAction extends Action { } echo MyAction::n(); //displays MyAction
从5.5开始,你可以使用class
关键字来进行类名parsing ,这比做函数调用要快得多。 也适用于接口。
// 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
这不是理想的解决scheme,但它适用于PHP <5.3.0。
代码是从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(); } }
现在(当5.3到达时)很简单:
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();
在可用的PHP版本中,没有办法做到你想要的。 保罗·迪克森的解决scheme是唯一的解决scheme。 我的意思是,代码示例,因为他谈论的后期静态绑定function可以在PHP 5.3中使用,它处于testing阶段。