2009-08-14 15 views
17

मैं इस क्षेत्र में अब दिनों से संघर्ष कर रहा हूं, और मैं एक निष्कर्ष तक पहुंच गया हूं, लेकिन जब तक मैं हारने से पहले निष्कर्ष नहीं ढूंढ रहा था, तो मैं यह देखने की कोशिश करूंगा कि मैं क्या देख रहा हूं अन्य लोग कहते हैं। विश्वास आखिरी मर जाता है ...विस्तारित PHP स्थैतिक वर्ग

मान लें कि हमारे पास एक सुपरक्लास (जिसे "सुपर" कहा जाता है) और उप-वर्ग (जिसे "सब" कहा जाता है) है।

class Super { 
    protected static $title = 'super'; 
    public static function get_class_name()   
    { 
     echo __CLASS__; 
    } 
    public static function get_title() 
    { 
     echo self::$title; 
    } 
} 
class Sub extends Super { 
    protected static $title = 'sub'; 
} 

अब, आप शायद उम्मीद करेंगे के बाद से उप सुपर फैली हुई है, कि उप अब सुपर के तरीकों के सभी के वारिस हैं, तथापि, यह केवल उप के तरीकों के लिए संदर्भ प्राप्त करने के लिए लगता है।

मैं यह कहना है क्योंकि अगर मैं फोन:

Sub::get_class_name(); 

उत्पादन होता है "सुपर", और नहीं "सब"।

और अगर मैं फोन:

Sub::get_title(); 

फिर, उत्पादन "सुपर" है, और मैं भी $ शीर्षक उप में घोषित किया है।

तो इसका मतलब है कि जब मैं विरासत में स्थिर कार्य कहता हूं, तो फ़ंक्शन का दायरा सुपर क्लास होगा, जिसे कॉल नहीं किया जाता है (भले ही आप बैकट्रैक प्रिंट करते हैं, यह दिखाएगा कि कॉल सुपरक्लास पर किया गया था! !!), और इस कॉल को प्राप्त करने के लिए उप-वर्ग के रूप में दायरे को प्राप्त करने के लिए, मुझे उस सबक्लास के अंदर उस विधि को फिर से शुरू करने की आवश्यकता है। वैसे इस तरह के वर्गों को विस्तारित करने के उद्देश्य को हराता है, है ना?

तो मेरा सवाल यह है कि, क्या मैं कभी भी स्थिर वर्ग का विस्तार कर सकता हूं, विरासत में से किसी एक को कॉल कर सकता हूं और सबक्लास का दायरा रख सकता हूं? या कम से कम इसके वर्ग नाम की पहचान करने में सक्षम होने के लिए? और यदि नहीं, तो मैं कभी भी स्थिर कक्षाओं का विस्तार क्यों करना चाहूंगा?

धन्यवाद!

उत्तर

28

फिर से, यह PHP 5.3.0 से पहले संभव नहीं है।

Late Static Binding PHP 5.3.0 में पेश किया गया था और आपको static कीवर्ड के माध्यम से वही करना है जो आप चाहते हैं।

class Super { 
    protected static $title = 'super'; 
    public static function get_class_name()   
    { 
     echo __CLASS__; 
    } 
    public static function get_title() 
    { 
     echo static::$title; 
    } 
} 
class Sub extends Super { 
    protected static $title = 'sub'; 
} 

get_class_name() अभी भी वापस आ जाएगी Super हालांकि है __CLASS__ हमेशा वर्तमान वर्ग (एक तरह से __FILE__ की तरह जो हमेशा वर्तमान फ़ाइल कोई फर्क नहीं पड़ता अगर आप इसे शामिल है या नहीं देता है) विधि जा रहा है समय में घोषित किया जाता है देता है।

इसके लिए आपके पास Sub कक्षा में फ़ंक्शन को फिर से घोषित करने के अलावा कोई विकल्प नहीं है।

class Super { 
    protected static $title = 'super'; 
    public static function get_class_name()   
    { 
     echo __CLASS__; 
    } 
    public static function get_title() 
    { 
     echo static::$title; 
    } 
} 
class Sub extends Super { 
    protected static $title = 'sub'; 

    public static function get_class_name()   
    { 
     echo __CLASS__; 
    } 
} 
+0

ठीक है, अब मुझे यह मिल गया है। – treznik

3

आप get_called_class() इस्तेमाल किया वर्ग आप बुला रहे हैं के वर्ग के नाम प्राप्त करने के लिए कर सकते हैं, भले ही वह स्थिर है। आपको इसे कहीं भी घोषित करने की आवश्यकता नहीं है।

एंड्रयू उदाहरण से:

class Super { 
    public static function get_class1_name()   
    { 
     echo __CLASS__; 
    } 
    public static function get_title() 
    { 
     echo get_called_class(); 
    } 

} 
class Sub extends Super {  
    public static function get_class2_name()   
    { 
     echo __CLASS__; 
    } 

} 
Sub::get_title(); // Echos Sub. 
Sub::get_class1_Name(); // echos super 
Sub::get_class2_Name(); // echos sub 

इसलिए आप किसी भी चर घोषित करने के लिए नहीं है।

+0

जो PHP 5.3.0 –

+1

से शुरू हो रहा है स्वीकार्य उत्तर केवल PHP 5.3.0 है। – Lethargy

+0

यह उदाहरण उप और सुपर कक्षाओं के बीच स्थिर गुणों तक पहुंचने में अंतर को संबोधित नहीं करता है। – beporter

0

सौभाग्य से, मैं अपने लिए कुछ कर रहा हूं, इसलिए मैंने कहा, इसे पेंच, मैं PHP5.3 का उपयोग कर रहा हूं। लेकिन फिर भी, मुझे यह पसंद नहीं है कि मुझे हर वर्ग में "_class _name" प्राप्त करना होगा, शायद मैं 10 कक्षाओं की तरह विस्तार कर रहा हूं। इसलिए मैं इस समाधान के साथ आया था:

class Super { 
    protected static $classname = __CLASS__; 
    public static function get_classname($name) 
    { 
     static::$classname = $name; 
    } 
    public static function get_classname() 
    { 
     return static::$classname; 
    } 
} 
class Sub1 extends Super { } 
class Sub2 extends Super { } 
class Sub3 extends Super { } 

$classes = get_declared_classes(); 
foreach($classes as $k => $v) 
{ 
    if (is_subclass_of($v, 'Super')) 
    { 
     $v::set_classname($v); 
    } 
} 

echo Sub1::get_classname(); // Sub1 
echo Sub2::get_classname(); // Sub2 
echo Sub3::get_classname(); // Sub3 

यह थोड़ा गंदा लग सकता है, लेकिन मैं यह है कि बुरा है नहीं लगता। ऐसा करने के साथ, आप आखिरकार विधियों को फिर से घोषित किए बिना स्थिर तरीकों का विस्तार कर सकते हैं।

+2

जैसा कि चाचा 102 के उत्तर में बताया गया है, PHP 5.3 में भी [get_called_class() फ़ंक्शन] है (http://uk3.php.net/manual/en/function.get-called-class.php) जो इस कामकाज को अनिवार्य बनाता है। – MrWhite

संबंधित मुद्दे