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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/506705/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 22:56:22  来源:igfitidea点击:

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

phpoopinheritance

提问by Anton

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

我有两个类:ActionMyAction。后者声明为:

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

All I need is method in the Actionclass (only in it, because there will be a lot of inherited classes, and I don't want to implement this method in all of them), which will return classname from a static call. Here is what I'm talking about:

我只需要Action类中的方法(仅在类中,因为会有很多继承的类,我不想在所有类中都实现这个方法),它将从静态调用中返回类名。这就是我要说的:

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 __CLASS__variable, which has the value “Action”.

但是父类中的每个声明只能访问父类__CLASS__变量,其值为“Action”。

Is there any possible way to do this?

有没有可能的方法来做到这一点?

回答by Paul Dixon

__CLASS__always returns the name of the class in which it was used, so it's not much help with a static method. If the method wasn't static you could simply use get_class($this). e.g.

__CLASS__总是返回使用它的类的名称,所以它对静态方法没有太大帮助。如果该方法不是静态的,您可以简单地使用get_class($this)。例如

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+

后期静态绑定,在 PHP 5.3+ 中可用

Now that PHP 5.3 is released, you can use late static bindings, which let you resolve the target class for a static method call at runtime rather than when it is defined.

现在 PHP 5.3 发布了,您可以使用后期静态绑定,它允许您在运行时而不是在定义时解析静态方法调用的目标类。

While the feature does not introduce a new magic constant to tell you the classname you were called through, it does provide a new function, get_called_class()which can tell you the name of the class a static method was called in. Here's an example:

虽然该特性没有引入一个新的魔法常量来告诉你你被调用的类名,但它确实提供了一个新函数get_Called_class(),它可以告诉你一个静态方法被调用的类的名称。 这是一个例子:

Class Action {
    public static function n() {
        return get_called_class();
    }
}


class MyAction extends Action {

}


echo MyAction::n(); //displays MyAction

回答by Ian Bytchek

Since 5.5 you can use classkeyword for the class name resolution, which would be a lot faster than making function calls. Also works with interfaces.

从 5.5 开始,您可以使用class关键字来解析类名,这比进行函数调用要快得多。也适用于接口。

// 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

回答by Jrgns

It's not the ideal solution, but it works on PHP < 5.3.0.

这不是理想的解决方案,但它适用于 PHP < 5.3.0。

The code was copied from septuro.com

该代码是从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();
    }
}

回答by src091

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

现在(当 5.3 到来时)它非常简单:

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

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

回答by Lulu

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();

回答by Ionu? G. Stan

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

在可用的 PHP 版本中,没有办法做你想做的事。Paul Dixon 的解决方案是唯一的。我的意思是,代码示例,因为他正在谈论的后期静态绑定功能在 PHP 5.3 中可用,这是测试版。