ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

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

Class Action {
 function n(){/* something */}
}

当我称之为:

MyAction::n(); // it should return "MyAction"

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

有没有办法做到这一点?


P
Paul Dixon

__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

OP 的唯一问题是该功能尚不可用。 PHP 5.3 还处于测试阶段。
@保罗,谢谢!你刚刚用 get_called_class() 拯救了我的一天……或夜晚 :)
我希望有人可以帮助我解决similar issue。 PHP 脚本在从私有静态方法内部执行 new static(); 时静默死掉(在 windows 上使用 xampp 和 php>5.5)。 :s
$foo=新的我的行动;回声 get_class($foo);这也会打印 MyAction。
I
Ian Bytchek

从 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

get_class::class 可能返回不同的结果(区分大小写)。详细信息在这里 - stackoverflow.com/questions/34118725/…
J
Jrgns

这不是理想的解决方案,但它适用于 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();
    }
}

T
T30

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

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


现在(当 5.5 到来时(很久以前))它更加简单:stackoverflow.com/a/25694818/458356
Q
Quamis
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();

B
Biswajit Biswas

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

this link might be helpfull


使用static::class
I
Ionuț G. Stan

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