2011-12-05 9 views
80

पीएचपी मैनुअल राज्यों

यह पीएचपी से पहले 5.4.0

गुमनाम समारोह से $this उपयोग करने के लिए संभव नहीं है anonymous functions page पर। लेकिन मुझे पता चला है कि मैं इसे $this को एक चर के लिए असाइन करके और चर परिभाषित करने पर use कथन को चर से गुजरकर इसे काम कर सकता हूं।

$CI = $this; 
$callback = function() use ($CI) { 
    $CI->public_method(); 
}; 

क्या यह एक अच्छा अभ्यास है?
क्या PHP 5.3 का उपयोग कर अज्ञात फ़ंक्शन के अंदर $this तक पहुंचने का कोई बेहतर तरीका है?

+1

बस एक छोटी सी मंच सम्मेलन - यह आमतौर पर एक प्रश्न अपना पसंदीदा जवाब प्रतिबिंबित करने के लिए संपादित करने के लिए की तुलना में एक जवाब स्वीकार करने के लिए बेहतर है। मुख्य रूप से ऐसा इसलिए होता है कि प्रतिक्रियाएं हमेशा शाश्वतता में समझ में आती हैं, बल्कि सही उत्तर के लिए क्रेडिट देने के लिए भी। – halfer

+3

सावधान रहें कि '$ सीआई = $ यह;' और '$ सीआई = और $ यह; ** ** वास्तव में समान नहीं हैं। शायद आपके उद्देश्यों के लिए, लेकिन वे वही नहीं हैं। '$ सीआई = 'ब्लै' का प्रयास करें; var_dump ($ यह); 'दोनों संस्करणों के साथ अंतर देखने के लिए। – Rudie

+1

@ रुडी मैं आपकी टिप्पणी के लिए [प्रलेखन] (http://php.net/manual/en/language.oop5.references.php) जोड़ रहा हूं – steampowered

उत्तर

61

जब आप उस पर एक सुरक्षित या निजी विधि कॉल करने का प्रयास करते हैं तो यह असफल हो जाएगा, क्योंकि इसका उपयोग बाहरी तरीके से कॉल करने के रूप में किया जाता है। 5.3 में इससे बचने के लिए जहाँ तक मुझे पता है, लेकिन आने पीएचपी 5.4 कोई तरीका नहीं है, यह उम्मीद के रूप में काम करेंगे, बॉक्स से बाहर:

class Hello { 

    private $message = "Hello world\n"; 

    public function createClosure() { 
     return function() { 
      echo $this->message; 
     }; 
    } 

} 
$hello = new Hello(); 
$helloPrinter = $hello->createClosure(); 
$helloPrinter(); // outputs "Hello world" 

इससे भी अधिक, तुम क्या $ बदलने के लिए सक्षम हो जाएगा इस क्रम में करने के लिए बताते हैं, Anonymus कार्य (बंद rebinding) के लिए:

class Hello { 

    private $message = "Hello world\n"; 

    public function createClosure() { 
     return function() { 
      echo $this->message; 
     }; 
    } 

} 

class Bye { 

    private $message = "Bye world\n"; 

} 

$hello = new Hello(); 
$helloPrinter = $hello->createClosure(); 

$bye = new Bye(); 
$byePrinter = $helloPrinter->bindTo($bye, $bye); 
$byePrinter(); // outputs "Bye world" 

प्रभावी ढंग से, Anonymus कार्यों एक bindTo() method है, जिसकी पहली पैरामीटर क्या करने के लिए इस अंक $ निर्दिष्ट करने के लिए इस्तेमाल किया जा सकता है, और दूसरा पैरामीटर नियंत्रण होगा दृश्यता स्तर क्या होना चाहिए। यदि आप दूसरा पैरामीटर छोड़ देते हैं, तो दृश्यता "बाहरी" से कॉल करने की तरह होगी, उदाहरण के लिए। केवल सार्वजनिक संपत्तियों का उपयोग किया जा सकता है। यह भी ध्यान दें कि बाइंडो काम करता है, यह मूल फ़ंक्शन को संशोधित नहीं करता है, यह एक नया देता है।

+1

अपने उत्तर को सही चिह्नित करना, लेकिन केवल अन्य पाठकों के लिए स्पष्टीकरण देना: सम्मेलन प्रश्न में इस्तेमाल किया गया ऑब्जेक्ट का उपयोग करके सार्वजनिक विधियों के लिए काम करेगा जो '$ this' का संदर्भ दे रहा है। – steampowered

+5

[गैर-सार्वजनिक तरीकों] (http://stackoverflow.com/a/6386863/90527) प्रतिबिंब का उपयोग करके पहुंचा जा सकता है। अक्षम और थोड़ा बुराई, लेकिन यह काम करता है। – outis

1

यह ठीक लगता है अगर संदर्भ से गुजरना यह सही तरीका है। यदि आप PHP 5 का उपयोग करते हैं तो आपको &$this से पहले प्रतीक की आवश्यकता नहीं है क्योंकि यह हमेशा संदर्भ के अनुसार संदर्भित होगा।

+2

ओपी 5.3 या उससे अधिक का उपयोग करना चाहिए, क्योंकि 4.x ने अज्ञात कार्यों का समर्थन नहीं किया है :-) – halfer

1

यह ठीक है। ...

$CI = $this; 

के बाद से वस्तुओं को शामिल assignations हमेशा संदर्भ, न कि पूरी वस्तुओं की प्रतिलिपि बनाएगा: मुझे लगता है चाहिए आप भी ऐसा कर सकता है।

5

यह सामान्य तरीका है जो किया गया था।
b.t.w, & को हटाने का प्रयास करें, इसके बिना इसे काम करना चाहिए, क्योंकि ऑब्जेक्ट किसी भी तरह से रेफर करते हैं।

5

संदर्भ द्वारा वस्तुओं को पारित करने के लिए हमेशा PHP पर भरोसा न करें, जब आप स्वयं को संदर्भ निर्दिष्ट कर रहे हों, तो व्यवहार अधिकांश ओओ भाषाओं में समान नहीं है जहां मूल सूचक संशोधित होता है।

अपने उदाहरण:

$CI = $this; 
$callback = function() use ($CI) { 
$CI->public_method(); 
}; 

होना चाहिए:

$CI = $this; 
$callback = function() use (&$CI) { 
$CI->public_method(); 
}; 

नोट संदर्भ "&" और $ सीआई अंतिम कॉल के बाद सौंपा जाना चाहिए पर यह किया गया है, फिर किसी और आप हो सकता है अप्रत्याशित आउटपुट, एक संदर्भ तक पहुंचने वाले PHP में मूल वर्ग तक पहुंचने के समान नहीं होता है - अगर यह समझ में आता है।

http://php.net/manual/en/language.references.pass.php

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