Genişletilmiş bir PHP sınıfında bir statik çağrıdan sınıf adını nasıl alabilirim?


93

İki sınıfım var: Actionve MyAction. İkincisi şu şekilde ilan edilir:

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

İhtiyacım olan Actiontek şey, sınıfta (yalnızca içinde, çünkü çok sayıda devralınan sınıf olacağı ve bu yöntemi hepsinde uygulamak istemiyorum), statik bir çağrıdan sınıf adını döndürecektir. İşte bahsettiğim şey:

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

Ve onu aradığımda:

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

Ancak üst sınıftaki her bildirim, yalnızca __CLASS__"Action" değerine sahip olan üst sınıf değişkenine erişime sahiptir.

Bunu yapmanın herhangi bir yolu var mı?

Yanıtlar:


176

__CLASS__her zaman içinde kullanıldığı sınıfın adını döndürür, bu nedenle statik bir yöntemin pek yardımı olmaz. Yöntem statik değilse, basitçe get_class ($ this) kullanabilirsiniz. Örneğin

class Action {
    public function n(){
        echo get_class($this);
    }

}

class MyAction extends Action {

}

$foo=new MyAction;

$foo->n(); //displays 'MyAction'

PHP 5.3+ sürümlerinde kullanılabilen geç statik bağlamalar

Artık PHP 5.3 piyasaya sürüldüğüne göre, statik bir yöntem çağrısı için hedef sınıfı tanımlandığı zamandan ziyade çalışma zamanında çözmenize izin veren geç statik bağlamaları kullanabilirsiniz .

Özellik, çağrıldığınız sınıf adını size söyleyen yeni bir sihirli sabit sağlamazken, statik bir yöntemin çağrıldığı sınıfın adını size söyleyebilecek yeni bir işlev, get_called_class () sağlar . İşte bir örnek:

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


class MyAction extends Action {

}


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

OP için tek sorun, özelliğin henüz mevcut olmamasıdır. PHP 5.3 henüz beta aşamasındadır.
Ionuț G. Stan

3
@Paul, teşekkürler! get_called_class()
Günümü

1
Keşke biri bana benzer bir konuda yardım edebilsin . PHP betiği new static();, özel bir statik yöntemin içinden çalıştırıldığında (Windows'ta xampp ve php> 5.5 kullanarak) sessizce ölür . :s
Stphane

$ foo = new MyAction; echo get_class ($ foo); Bu ayrıca MyAction'ı da yazdırır.
sammry


16

İdeal bir çözüm değil, ancak PHP <5.3.0'da çalışıyor.

Kod septuro.com'dan kopyalandı

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

Mevcut PHP sürümlerinde istediğinizi yapmanın bir yolu yoktur. Paul Dixon'ın çözümü tek çözümdür. Demek istediğim, kod örneği, bahsettiği son statik bağlama özelliği, beta sürümünde olan PHP 5.3'ten itibaren mevcuttur.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.