我有两个类:Action
和 MyAction
。后者声明为:
class MyAction extends Action {/* some methods here */}
我只需要 Action
类中的方法(仅在其中,因为会有很多继承的类,我不想在所有这些类中都实现此方法),它将从静态调用返回类名.这就是我所说的:
Class Action {
function n(){/* something */}
}
当我称之为:
MyAction::n(); // it should return "MyAction"
但是父类中的每个声明只能访问父类 __CLASS__
变量,该变量的值为“Action”。
有没有办法做到这一点?
__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 发布了,您可以使用 late static bindings,它让您在运行时而不是在定义静态方法调用时解析目标类。
虽然该功能没有引入新的魔术常量来告诉您被调用的类名,但它确实提供了一个新函数 get_called_class(),它可以告诉您调用静态方法的类的名称。下面是一个示例:
Class Action {
public static function n() {
return get_called_class();
}
}
class MyAction extends Action {
}
echo MyAction::n(); //displays MyAction
从 5.5 开始,您可以use class
keyword for the class name resolution,这比进行函数调用要快得多。也适用于接口。
// 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 复制的
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
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 5 >= 5.3.0, PHP 7) get_call_class — “后期静态绑定”类名
<?php
class Model
{
public static function find()
{
return get_called_class();
}
}
class User extends Model
{
}
echo User::find();
static::class
在可用的 PHP 版本中,没有办法做你想做的事。 Paul Dixon 的解决方案是唯一的。我的意思是,代码示例,因为他所说的后期静态绑定功能在 PHP 5.3 中可用,该版本处于测试阶段。
get_called_class()
拯救了我的一天……或夜晚 :)new static();
时静默死掉(在 windows 上使用 xampp 和 php>5.5)。:s