PHP में 5.4.0 में एक अनाम फ़ंक्शन में `$ this` का उपयोग करना


86

PHP मैनुअल बताता है

$thisPHP 5.4.0 से पहले अनाम फ़ंक्शन का उपयोग करना संभव नहीं है

पर अनाम प्रक्रियाएं पेज । लेकिन मैंने पाया है कि मैं $thisएक चर को असाइन करके और useकार्य को परिभाषा में एक बयान में चर को पास करके काम कर सकता हूं ।

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

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


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

4
खबरदार है कि $CI = $this;और वास्तव में समान $CI =& $this; नहीं हैं। शायद आपके उद्देश्यों के लिए, लेकिन वे समान नहीं हैं। $CI = 'bla'; var_dump($this);अंतर देखने के लिए दोनों संस्करणों के साथ प्रयास करें ।
रुडी

1
@ रुडी मैं आपकी टिप्पणी के लिए प्रलेखन जोड़ रहा हूँ
वाष्पीकृत

@steampowered इस बारे में कहीं न कहीं एक अच्छा उदाहरण / लेख ऑनलाइन है, लेकिन मैं इसे नहीं पा सका =) क्षमा करें। यदि आप अंतर नहीं देखते हैं तो बस इसे आज़माएं। यह तो स्पष्ट है।
रुडी

जवाबों:


67

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

इससे भी अधिक, आप अनाम समय के कार्यों के लिए रनटाइम के दौरान इस बिंदु को $ कितना बदल पाएंगे, (रिबंडिंग बंद करना):

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"

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


1
अपने उत्तर को सही तरीके से चिह्नित करें, लेकिन अन्य पाठकों के लिए स्पष्ट करने के लिए: प्रश्न में प्रयुक्त कन्वेंशन उस ऑब्जेक्ट का उपयोग करके सार्वजनिक तरीकों के लिए काम करेगा जो संदर्भित है $this
वाष्पीकृत

5
गैर-सार्वजनिक तरीकों को प्रतिबिंब का उपयोग करके एक्सेस किया जा सकता है। अक्षम और थोड़ी सी बुराई, लेकिन यह काम करता है।
outis

7

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

आपका उदाहरण:

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

होना चाहिए:

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

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

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


6

यह सामान्य तरीका है।
btw, &इसे हटाने के लिए इसे बिना काम करना चाहिए, क्योंकि ऑब्जेक्ट किसी भी तरह से रेफरी से गुजरते हैं।


1

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


2
ओपी का उपयोग 5.3 या अधिक से अधिक होना चाहिए, क्योंकि 4.x ने अनाम फ़ंक्शंस का समर्थन नहीं किया :-)
आधा करें

1

यह ठीक है। मुझे लगता है कि आपको यह भी करना चाहिए:

$CI = $this;

... चूंकि वस्तुओं को शामिल करने वाले असाइनमेंट हमेशा संदर्भों की नकल करेंगे, न कि पूरी वस्तुओं की।

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