मैं विस्तारित PHP कक्षा में स्थिर कॉल से क्लासनाम कैसे प्राप्त कर सकता हूं?


93

मेरे पास दो वर्ग हैं: Actionऔर MyAction। बाद के रूप में घोषित किया गया है:

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

मुझे Actionकेवल कक्षा में विधि की आवश्यकता है (केवल इसमें, क्योंकि बहुत सारी विरासत वाली कक्षाएं होंगी, और मैं उन सभी में इस पद्धति को लागू नहीं करना चाहता), जो एक स्थिर कॉल से क्लासनाम वापस कर देगा। यहाँ मैं बात कर रहा हूँ:

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

और जब मैं इसे कॉल करता हूं:

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

लेकिन मूल वर्ग में प्रत्येक घोषणा में केवल मूल वर्ग __CLASS__चर तक पहुंच होती है , जिसका मूल्य "एक्शन" होता है।

क्या ऐसा करने का कोई संभावित तरीका है?

जवाबों:


176

__CLASS__हमेशा उस वर्ग का नाम लौटाता है जिसमें इसका उपयोग किया गया था, इसलिए यह स्थैतिक विधि से बहुत मदद नहीं करता है। यदि विधि स्थिर नहीं थी, तो आप बस get_class ($ यह) का उपयोग कर सकते थे । जैसे

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

ओपी के लिए एकमात्र समस्या यह है कि यह सुविधा अभी तक उपलब्ध नहीं है। PHP 5.3 अभी बीटा में है।
इयोनू जी। स्टेन

3
@ पाओल, धन्यवाद! आपने अभी-अभी मेरा दिन बचाया है ... या रात को get_called_class():)
मेरीके

1
काश कोई इसी तरह के मुद्दे पर मेरी मदद कर सके । PHP स्क्रिप्ट new static();एक निजी स्थैतिक विधि (विंडोज़ और php> 5.5 पर xampp का उपयोग करके) के अंदर से निष्पादित होने पर चुपचाप मर जाती है । :s
स्टेफेन

$ फू = नया मायएशन; इको get_class ($ फू); यह MyAction को भी प्रिंट करता है।
शाम

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 संस्करणों में, आप क्या चाहते हैं, इसका कोई तरीका नहीं है। पॉल डिक्सन का समाधान एकमात्र है। मेरा मतलब है, कोड उदाहरण, देर से स्थिर बाइंडिंग सुविधा के बारे में वह बात कर रहा है जो PHP 5.3 के रूप में उपलब्ध है, जो बीटा में है।


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.