如何从扩展的PHP类中的静态调用获取类名?

我有两个类: ActionMyAction 。 后者被宣布为:

 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到达时)很简单:

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

 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阶段。