확장 된 PHP 클래스의 정적 호출에서 클래스 이름을 어떻게 얻을 수 있습니까?


93

두 가지 클래스가 있습니다 : ActionMyAction. 후자는 다음과 같이 선언됩니다.

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
@ 폴, 감사합니다! 당신은 내 일 ... 밤을 저장 get_called_class():
Marecky

1
누군가 비슷한 문제로 나를 도울 수 있기를 바랍니다 . PHP 스크립트 new static();는 비공개 정적 메서드 (Windows에서 xampp 사용 및 php> 5.5 사용) 내에서 실행시 자동으로 종료됩니다 . :s
Stphane 16.10.25

$ foo = new MyAction; echo get_class ($ foo); 이것은 또한 MyAction을 인쇄합니다.
sammry

41

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

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 버전에서는 원하는 작업을 수행 할 수 없습니다. Paul Dixon의 솔루션은 유일한 솔루션입니다. 내 말은, 그가 말하고있는 후기 정적 바인딩 기능은 베타 버전 인 PHP 5.3부터 사용할 수있는 코드 예제입니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.