How can I get the classname from a static call in an extended PHP class?
我有两个班:
1 | class MyAction extends Action {/* some methods here */} |
我只需要
1 2 3 | Class Action { function n(){/* something */} } |
当我称之为:
1 | MyAction::n(); // it should return"MyAction" |
但是父类中的每个声明都只能访问父类
有什么可行的方法吗?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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,那么可以使用后期的静态绑定,这样可以在运行时而不是在定义静态方法时解析静态方法调用的目标类。
虽然这个特性没有引入一个新的魔力常数来告诉你被调用的类名,但是它提供了一个新的函数get _called _class(),它可以告诉你一个静态方法被调用的类的名称。下面是一个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 | Class Action { public static function n() { return get_called_class(); } } class MyAction extends Action { } echo MyAction::n(); //displays MyAction |
由于5.5,您可以使用
1 2 3 4 5 6 | // 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 |
这不是理想的解决方案,但它适用于php<5.3.0。
代码是从septuro.com复制的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | 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://php.net/manual/en/function.get-called-class.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | 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版本中,无法执行您想要的操作。保罗·狄克逊的解决方案是唯一的。我的意思是,这个代码示例,作为他所说的最新的静态绑定特性,可以从PHP5.3开始使用,后者是beta版本。