2012-12-12 41 views
7

मैं एक PHP कोड है कि इस तरह दिखता है:

class A { 
    public function __construct() { 
     $this->b = new B(function($x) { return $x + 1; }); 
    } 
}; 

class B { 
    public function __construct($dataProcessingFunction) { 
     $this->dataProcessingFunction = $dataProcessingFunction; 
    } 

    public function processData($data) { 
     $f = $this->dataProcessingFunction; 
     return $f($data); 
    } 
}; 

लेकिन वहाँ एक समस्या है: मैं बिल्कुल बी नाशक की जरूरत है एक नाशक से पहले कहा जाता है। यह उचित लगता है जैसा आप देख सकते हैं। बी ऑब्जेक्ट को किसी भी ए की आवश्यकता नहीं है, इसलिए कोई समस्या नहीं होनी चाहिए।

लेकिन PHP 5.4.0 के बाद, बंद होने से स्वचालित रूप से $ 1. पर कब्जा प्रतीत होता है। इसलिए, लैम्बडा फ़ंक्शन जिसे मैं बी पास करता हूं और जिसे बी द्वारा संग्रहीत किया जाता है, में ए

का अर्थ होता है जिसका अर्थ है कि ए में बी के लिए सूचक होता है, और बी में ए (बंद होने के माध्यम से) के सूचक होते हैं। इस तरह की स्थिति में, पीएचपी दस्तावेज कहता है कि विनाशकों को केवल कचरा संग्रह और यादृच्छिक क्रम में बुलाया जाता है। और अनुमान लगाएं: बी के विनाशक को हमेशा ए के सामने बुलाया जाता है।

क्या यह एक सुरुचिपूर्ण तरीके से इसे हल करने का कोई तरीका है?

+0

"प्रतीत नहीं होता" - निश्चित रूप से, जैसा कि एनन func changelog में इंगित किया गया है: http://php.net/manual/en/functions.anonymous.php –

+0

सबसे सुंदर तरीका जो मैं सोच सकता हूं वह आपके कोड को बदलना होगा ताकि आप एक विनाशक आदेश पर निर्भर नहीं हैं। इस तरह के एक विशिष्ट आदेश पर निर्भर होने से आपको परेशानी हो सकती है। – RonaldBarzell

+0

मेरे पास PHP 5.4 नहीं है जहां मैं हूं इसलिए मैं परीक्षण नहीं कर सकता, लेकिन 'create_function' का उपयोग करने का प्रयास करें। आप 'क्लोजर' क्लास का उपयोग करने में सक्षम हो सकते हैं, या केवल उस फ़ंक्शन को बदल सकते हैं जो फ़ंक्शन से जुड़ा हुआ है (इतना गुमनाम नहीं है कि असाइनमेंट की आवश्यकता होगी, मुझे लगता है)। –

उत्तर

4

विस्फोट गोलियों के लिए धन्यवाद, मुझे Closure कक्षा में समाधान मिला है।

आप वास्तव में बदल सकते हैं $this, बंद के अंदर संग्रहित इस तरह:

$cb = function($x) { return $x + 1; }; 
$cb = $cb->bindTo(null); 

// now $cb doesn't contain a pointer to $this anymore 

ध्यान दें कि यदि आप ऐसा नहीं कर सकते हैं, या आप एक सिंटैक्स त्रुटि मिल जाएगा:

// syntax error 
$cb = (function($x) { return $x + 1; })->bindTo(null); 
+0

डी ओह .. यह मेरा प्रतिनिधि है! –

+0

आपको ढीला याद दिलाएं! –