2012-10-12 48 views
8

कभी-कभी मुझे दादा-दादी विधि (यानी, मूल विधि को बाईपास) निष्पादित करने की आवश्यकता होती है, मुझे पता है कि यह कोड गंध है, लेकिन कभी-कभी मैं अन्य वर्गों (ढांचे, पुस्तकालयों, आदि) को नहीं बदल सकता।E_STRICT त्रुटि प्राप्त किए बिना दादा-दादी विधि को कैसे कॉल करें?

सख्त मानकों:

call_user_func(array(get_parent_class(get_parent_class($childObject)), 'grandParentMethod')); 

समस्या अगर आपके पास है कि E_STRICT त्रुटियों सक्षम आप की तरह एक त्रुटि प्राप्त होगी है: गैर स्थैतिक विधि

पीएचपी में हम साथ कुछ की तरह ऐसा कर सकते हैं GrandParent :: grandParentMethod() को स्थिर रूप से नहीं कहा जाना चाहिए ...

मुझे इसके लिए केवल एक समाधान मिला है (E_STRICT को हटाए बिना), और यह केवल @ को जोड़ रहा है त्रुटि को उतारो।

लेकिन यह वास्तव में बदसूरत है, क्या कोई बेहतर समाधान जानता है?

धन्यवाद! पुनश्च: मैं की तरह एक नई वस्तु का दृष्टांत नहीं कर सकते हैं:

$grandparent = get_parent_class(get_parent_class($son)); 
$gp= new $grandparent; 
$gp->grandParentMethod 

क्योंकि मैं $ बेटे के संदर्भ में मेरे दादा-दादी विधि कॉल करने की जरूरत है।

+0

अरे एनरिक, क्रिंकल के उत्तर की तरह दिखता है और अधिक उपयुक्त और स्पष्ट है। दादा वर्ग से इसे एक्सेस करने के लिए आपको दादा वर्ग पर सार्वजनिक पहुंच सेट करने की भी आवश्यकता नहीं है ... यदि आप सहमत हैं, तो क्या आप क्रिंकल के उत्तर के स्वीकृत उत्तर को बदल सकते हैं? – a20

उत्तर

2

आप उपयोग कर सकते हैं ReflectionMethod->invoke()

उदाहरण:

<?php 
class Grandpa { 
    protected $age = 'very old'; 
    public function sayMyAge() { 
     return 'sayMyAge() in Grandpa should be very old. ' . 
        'My age is: ' . $this->age; 
    } 
} 

class Pa extends Grandpa { 
    protected $age = 'less old'; 
    public function sayMyAge() { 
     return 'sayMyAge() in Pa should be less old. ' . 
        'My age is: ' . $this->age; 
    } 
} 

class Son extends Pa { 
    protected $age = 'younger'; 
    public function sayMyAge() { 
     return 'sayMyAge() in Son should be younger. ' . 
        'My age is: ' . $this->age; 
    } 
} 

$son = new Son(); 
$reflectionMethod = new ReflectionMethod(get_parent_class(get_parent_class($son)), 
             'sayMyAge'); 
echo $reflectionMethod->invoke($son); 
// returns: 
// sayMyAge() in Grandpa should be very old. My age is: younger 

नोट: लागू विधि सार्वजनिक होना चाहिए।

+0

मुझे लगता है कि हम गैर सार्वजनिक तरीकों के लिए सेट अक्षम करने का उपयोग कर सकते हैं। वैसे भी, यह यहाँ कहां है? ज्यादातर मामलों में मुझे अपने बेटे वर्ग के अंदर दादाजी का उपयोग करने की ज़रूरत है, और granparent को मेरे $ (बेटे) ऑब्जेक्ट पर चीजों को एक नया नहीं बदलना चाहिए। अजीब चीज यह है कि इस मामले में PHP (5.3.13) E_SRICT चेतावनी नहीं दिखा रहा है जब मैं कुछ ऐसा करता हूं: GrandParent :: method(); मेरे बेटे वर्ग के अंदर (और यह भी सही $ यह मान रहा है)। – Enrique

+1

मैं आपको नहीं बता सकता कि कक्षा के भीतर से 'ग्रैंडपेरेंट :: विधि() 'की कॉल क्यों STRICT-चेतावनी को मजबूर नहीं करती है। $ यह वह ऑब्जेक्ट होगा जो इस मामले में $ बेटे को विधि का आह्वान करेगा, इसलिए $ में परिवर्तन यह $ बेटे पर लागू होगा। –

+2

मेरे पास एक ही सवाल था, लेकिन [इस आधिकारिक बग रिपोर्ट] के अनुसार [http://stackoverflow.com/questions/12850802/how-to-call-grandparent-method-without-getting-e-strict-error), यदि संदर्भ सही है (मुझे लगता है कि इसका अर्थ है 'सबक्लास से'), 'ग्रैंडपेरेंट :: विधि()' कॉल सही ढंग से '$' सेट करेगा और इस गैर-स्थैतिक कॉल को स्थिर तरीके से अनुमति देगा। –

0

आप doStuff के पूरक के लिए एक अलग आंतरिक विधि (उदा। _doStuff) का उपयोग कर सकते हैं और माता-पिता के माध्यम से सीधे पोते से कॉल कर सकते हैं।

// Base class that everything inherits 
class Grandpa { 
    protected function _doStuff() { 
     // grandpa's logic 
     echo 'grandpa '; 
    } 

    public function doStuff() { 
     $this->_doStuff(); 
    } 

} 

class Papa extends Grandpa { 
    public function doStuff() { 
     parent::doStuff(); 
     echo 'papa '; 
    } 
} 

class Kiddo extends Papa { 
    public function doStuff() { 
     // Calls _doStuff instead of doStuff 
     parent::_doStuff(); 
     echo 'kiddo'; 
    } 
} 

$person = new Grandpa(); 
$person->doStuff(); 
echo "\n"; 
$person = new Papa(); 
$person->doStuff(); 
echo "\n"; 
$person = new Kiddo(); 
$person->doStuff(); 

से पता चलता

grandpa 
grandpa papa 
grandpa kiddo 
31

आप दादा-दादी सीधे नाम से (किसी भी call_user_func बंधन के बिना) कह सकते हैं।

class Base { 
    protected function getFoo() { 
     return 'Base'; 
    } 
} 

class Child extends Base { 
    protected function getFoo() { 
     return parent::getFoo() . ' Child'; 
    } 
} 

class Grandchild extends Child { 
    protected function getFoo() { 
     return Base::getFoo() . ' Grandchild'; 
    } 
} 

Base::getFoo कॉल (पेट के :: वाक्य रचना के कारण) एक स्थिर कॉल की तरह लग सकता है, लेकिन यह नहीं है। बस parent:: की तरह स्थिर नहीं है, या तो। कक्षा के भीतर विरासत श्रृंखला से एक विधि को कॉल करने से $this मूल्य सही ढंग से बाध्य हो जाएगा, इसे नियमित विधि के रूप में आमंत्रित करें, दृश्यता नियमों (जैसे संरक्षित) का सम्मान करें, और किसी भी प्रकार का उल्लंघन नहीं है। यह पहली बार थोड़ा अजीब लग सकता है, लेकिन PHP में ऐसा करने का यह तरीका है।

+3

स्वीकार्य उत्तर से यह एक बहुत साफ दृष्टिकोण है। मुझे यह भी पता नहीं था कि आप आज तक PHP में ऐसा कर सकते हैं ... धन्यवाद @ क्रिंकल – Brian

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

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