2013-12-09 4 views
10

क्या पैरामीटर के रूप में पारित होने वाले बंद होने के लिए $this को बांधने का कोई तरीका है? मैं मैन्युअल या इंटरनेट पर जो कुछ भी पा सकता हूं उसे पढ़ और पढ़ता हूं, लेकिन इस ब्लॉग पोस्ट को छोड़कर कोई भी इस व्यवहार का उल्लेख नहीं करता है: http://www.christophh.net/2011/10/26/closure-object-binding-in-php-54/ जो इसका उल्लेख करता है लेकिन यह नहीं दिखाता कि यह कैसे करना है।PHP 5.4 में विधि पैरामीटर के रूप में पारित होने वाले बंद होने के लिए इसे कैसे बाध्य करें?

तो यहां एक उदाहरण है। get(function() {}) विधि को कॉल करते समय मैं चाहता हूं कि इसे वापस कॉलबैक फ़ंक्शन ऑब्जेक्ट से बाध्य था यानी $this पर बाध्य था, लेकिन दुर्भाग्यवश यह काम नहीं करता है। क्या मैं ऐसा कर सकता हूं?

class APP 
{ 
    public $var = 25; 

    public function __construct() { 

    } 
    public function get($callback) { 
     if (!is_callable($callback)) { 
      throw new InvalidArgumentException('Paran must be callable.'); 
     } 
     // $callback->bindTo($this); 
     $callback->bindTo($this, $this); 
     $callback(); 
    } 
} 

$app = new APP(); 
$app->get(function() use ($app) { 
    echo '<pre>'; 
    var_dump($app); 
    echo '<br />'; 
    var_dump($this); 
}); 

$app काम करता है। $this शून्य है।

उत्तर

7
:

public function get($callback) { 
     if (!is_callable($callback)) { 
      throw new InvalidArgumentException('Paran must be callable.'); 
     } 
     // $callback->bindTo($this); 
     return $callback($this); 
    } 

... 

$app = new APP(); 
$app->get(function($that) use ($app) { 
    echo '<pre>'; 
    var_dump($app); 
    echo '<br />'; 
    var_dump($that); 
}); 

वैकल्पिक रूप से, अगर आप वास्तव में इसे बाध्य करने की जरूरत थी, तो आप एक समारोह है कि एक समारोह लौट आए, इस तरह का उपयोग करना होगा

मुझे वास्तव में समझ में नहीं आया कि bindTo विधि का उपयोग इस मामले में क्यों नहीं किया गया था, लेकिन मैं इसे Closure::bind

public function get($callback) { 
    if (!is_callable($callback)) { 
     throw new InvalidArgumentException('Param must be callable.'); 
    } 

    $bound = Closure::bind($callback, $this); 
    $bound(); 
} 
का उपयोग करके काम करने के लिए प्राप्त कर सकता था ताकि आप $callback करने के लिए अपनी वापसी मान पुन: असाइन करना चाहिए

संपादित

Aparently bindTo विधि, समान व्यवहार है। उदाहरण के लिए:

public function get($callback) { 
    if (!is_callable($callback)) { 
     throw new InvalidArgumentException('Param must be callable.'); 
    } 

    $callback = $callback->bindTo($this); 
    $callback(); 
} 
+1

अरे! बहुत बहुत धन्यवाद Guilherme!मैंने क्लोजर :: बाइंड की कोशिश की, लेकिन मुझे नहीं पता था कि यह वापसी मूल्य था जिसके बाद मुझे फोन करना चाहिए। –

+0

@ अज्ञात.बर्ड आपका स्वागत है। :) –

+6

और एक पंक्ति में '$ कॉलबैक-> बाइंडो ($ यह) -> __ invoke(); ':) –

1

बस एक तर्क के रूप में यह पारित:

public function getCallback($callback) { 
     return function($app){ 
      return $callback($this, $app); 
     } 
    } 

... 

$app = new APP(); 
$f = $app->get(function($that, $app) { 
    echo '<pre>'; 
    var_dump($app); 
    echo '<br />'; 
    var_dump($that); 
}); 
$f($app); 
+0

धन्यवाद बेनबर्ड (आपके नाम की तरह :)), मुझे पता है कि पहले से ही कामकाज (जैसा कि मैंने कहा था, मैं लगभग इस विषय के बारे में जो कुछ भी पा सकता हूं उसे पढ़ता हूं), लेकिन यह वास्तव में मेरे लिए बदसूरत लग रहा है, हालांकि अगर कोई भाषा बंद हो जाती है यह अधिक प्रत्यक्ष तरीके से प्राप्त किया जाना चाहिए। –

2

इस तरह करें:

class APP 
{ 
    public $var = 25; 

    public function __construct() {} 

    public function get($callback) { 
    if (!is_callable($callback)) { 
     throw new InvalidArgumentException('Param must be callable.'); 
    } 
    // $callback->bindTo($this); 
    // you must save result in another var and call it 
    $callback1 = $callback->bindTo($this, $this); 
    $callback1(); 
    } 
} 

$app = new APP(); 
$app->get(function() use ($app) { 
    echo '<pre>'; 
    var_dump($app); 
    echo '<br />'; 
    var_dump($this); 
}); 
+0

यह भी काम करता है! तो यह लौटने वाला बंद है जो मूल है और मूल नहीं है। –

1

एक छोटा सा सुधार: Closure पैरामीटर द्वारा पारित हो जाता है, तो जाँच करने के लिए is_callable प्रयोग नहीं करते।

क्योंकि is_callable भी कार्य के नाम के साथ स्ट्रिंग स्वीकार करते हैं।

$app = new App; 


$app->get('my_function'); 

समारोह मौजूद है, तो इस त्रुटि फेंक दिया जाता है:

public function get(\Closure $callback) { 

    $bound = \Closure::bind($callback, $this); 
    $bound(); 
} 
is_callable साथ

हम इस संभावना है

बंद :: बाँध() उम्मीद पैरामीटर 1 बंद, स्ट्रिंग होने के लिए

क्योंकि "My_function" 012 के परीक्षण में पारित किया गया है, लेकिन Closure::bindClosure के उदाहरण की अपेक्षा करता है।

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

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