Pertanyaan Bagaimana saya bisa mendapatkan classname dari panggilan statis di kelas PHP yang diperpanjang?


Saya memiliki dua kelas: Action dan MyAction. Yang terakhir ini dinyatakan sebagai:

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

Yang saya butuhkan hanyalah metode di Action kelas (hanya di dalamnya, karena akan ada banyak kelas yang diwariskan, dan saya tidak ingin menerapkan metode ini dalam semuanya), yang akan mengembalikan nama kelas dari panggilan statis. Inilah yang saya bicarakan:

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

Dan ketika saya menyebutnya:

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

Tetapi setiap deklarasi di kelas induk hanya memiliki akses ke kelas induk __CLASS__ variabel, yang memiliki nilai "Action".

Apakah ada cara yang mungkin untuk melakukan ini?


75
2018-02-03 11:04


asal


Jawaban:


__CLASS__ selalu mengembalikan nama kelas yang digunakan, jadi tidak banyak membantu dengan metode statis. Jika metode itu tidak statis Anda hanya bisa menggunakan get_class($ this). misalnya

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

}

class MyAction extends Action {

}

$foo=new MyAction;

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

Late static bindings, tersedia dalam PHP 5.3+

Sekarang PHP 5.3 dirilis, Anda dapat menggunakan binding statis terlambat, yang memungkinkan Anda menyelesaikan kelas target untuk pemanggilan metode statis saat runtime daripada ketika didefinisikan.

Meskipun fitur ini tidak memperkenalkan konstanta sihir baru untuk memberi tahu Anda nama kelas yang dipanggil, ia menyediakan fungsi baru, get_called_class () yang dapat memberi tahu Anda nama kelas metode statis dipanggil. Berikut ini contohnya:

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


class MyAction extends Action {

}


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

155
2018-02-03 11:16



Sejak 5.5 Anda bisa menggunakan class kata kunci untuk resolusi nama kelas, yang akan jauh lebih cepat daripada membuat panggilan fungsi. Juga berfungsi dengan antarmuka.

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

30
2017-09-05 22:28



Ini bukan solusi ideal, tetapi bekerja pada PHP <5.3.0.

Kode itu disalin dari 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();
    }
}

16
2017-10-09 06:07



Sekarang (ketika 5.3 telah tiba) itu sangat sederhana:

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


12
2017-09-27 12:36



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

2
2018-02-14 20:16



Tidak ada cara, dalam versi PHP yang tersedia, untuk melakukan apa yang Anda inginkan. Solusi Paul Dixon adalah satu-satunya. Maksudku, contoh kode, seperti fitur bindings statis yang dia bicarakan tersedia di PHP 5.3, yang dalam versi beta.


0
2018-02-03 11:27