拡張PHPクラスの静的呼び出しからクラス名を取得するにはどうすればよいですか?


91

との2つのクラスがActionありMyActionます。後者は次のように宣言されます。

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

必要なのはActionクラス内のメソッドだけです(継承されたクラスがたくさんあり、それらすべてにこのメソッドを実装したくないので、クラス内だけです)。これは静的呼び出しからクラス名を返します。これが私が話していることです:

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

そして私がそれを呼ぶとき:

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

ただし、親クラスの各宣言__CLASS__は、値「Action」を持つ親クラス変数にのみアクセスできます。

これを行うための可能な方法はありますか?

回答:


176

__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がリリースされたので、遅延静的バインディングを使用できます。これにより、静的メソッド呼び出しのターゲットクラスを、定義時ではなく実行時に解決できます。

この機能では、呼び出されたクラス名を通知する新しいマジック定数が導入されていませんが、静的メソッドが呼び出されたクラスの名前を通知できる新しい関数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はまだベータ版です。
Ionuț G. Stan

3
@Paul、ありがとう!あなたはちょうど私の日を保存しました...またはget_called_class():)で夜を保存しました
Marecky

1
私は誰かが同様の問題で私を助けてくれることを願っています。PHPスクリプトはnew static();、プライベート静的メソッド内から実行するとサイレントで終了します(Windowsでxamppを使用し、php> 5.5を使用)。:s
Stphane 2016年

$ foo = new MyAction; echo get_class($ foo); これはMyActionも出力します。
sammry 2018


16

これは理想的なソリューションではありませんが、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();
    }
}


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

0

利用可能なPHPバージョンでは、希望することを行う方法はありません。ポール・ディクソンのソリューションが唯一のものです。つまり、コード例は、彼が話しているレイトスタティックバインディング機能として、ベータ版のPHP 5.3以降で利用できます。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.