2010-02-05 12 views
9

क्या ग्लोबल का उपयोग न करने वाले PHP 5.2.x में बंद करना अनुकरण करना संभव है? मैं ऐसे तरीके से सोच सकता हूं जो वांछित चर को बंद करने के लिए अतिरिक्त पैरामीटर के रूप में पास करेगा लेकिन यह सर्वोत्तम अभ्यास की तरह महसूस नहीं करता है।क्या ग्लोबल का उपयोग न करने वाले PHP 5.2.x में बंद करना अनुकरण करना संभव है?

कोई विचार?

+0

यह वास्तव में दुखद है कि PHP इस तरह के एक अद्भुत निर्माण का समर्थन नहीं करता है। – ChaosPandion

+4

@CoosPandion लेकिन यह PHP5.3 से – Gordon

+0

अच्छी तरह से करता है, हां, लेकिन आपको स्पष्ट रूप से बंद चर सूचीबद्ध करना होगा। बोलने के लिए "क्रश पर बंद"। हालांकि कुछ भी नहीं से भी बेहतर है। – user187291

उत्तर

7

दिलचस्प सवाल। मैं कहेंगे यह सब पर संभव नहीं है, लेकिन

देख IBM - What's new in PHP5.3, Part 2

का हवाला देते हुए एक बंद एक समारोह है कि अपने परिवेश से मूल्यांकन किया जाता है, जो एक या अधिक बाध्य चर कि हो सकता है है जाने फ़ंक्शन कहलाते समय एक्सेस किया जाता है।

और आगे (जोर मेरा)

चर बाहर के वातावरण से बंद समारोह परिभाषा के उपयोग के खंड में निर्दिष्ट कर रहे हैं आयात करने के लिए। डिफ़ॉल्ट रूप से, वे मान द्वारा पारित किए जाते हैं, जिसका अर्थ है कि अगर हम बंद कार्य परिभाषा के भीतर पारित मान को अपडेट करेंगे, तो यह बाहरी मान को अपडेट नहीं करेगा।

global का उपयोग संदर्भ द्वारा और हालांकि यह use खंड में & का उपयोग करके एक बंद के साथ संदर्भ द्वारा चर बाध्य करने के लिए संभव है मिलेगा, इसलिये यह पहले से ही 5.3 डिफ़ॉल्ट व्यवहार से विचलन है।

$var = 'yes'; 
$fn = create_function('', 'global $var; $var = "no";'); 
$fn(); 
echo $var; // outputs no 

आप मूल्य के आधार पर इसका उपयोग करने के लिए वैश्विक चर की प्रतिलिपि बना सकते हैं, उदाहरण के लिए

$var = 'yes'; 
$fn = create_function('', 'global $var; $tmp = $var; $tmp = "no";'); 
$fn(); 
echo $var; // outputs yes 

इसके अलावा, वैश्विक चर (जब create_function का प्रयोग करके) के मूल्य में मूल्यांकन नहीं किया जाएगा (बाध्य) जब समारोह बनाई गई है लेकिन समारोह

$var = 'yes'; 
$fn = create_function('', 'global $var; $tmp = $var; return $tmp;'); 
$var = 'maybe'; 
echo $fn(); // outputs maybe 

$var = 'yes'; 
$fn = function() use ($var) { return $var; }; 
$var = 'maybe'; 
echo $fn(); // outputs yes 

चलाया जाता है जब भी महत्वपूर्ण

है

किसी ऑब्जेक्ट के भीतर परिभाषित होने पर, एक आसान बात यह है कि बंदरगाह को इस चर के माध्यम से ऑब्जेक्ट तक पूर्ण पहुंच है, इसे स्पष्ट रूप से आयात करने की आवश्यकता के बिना। * हालांकि मुझे लगता है कि इस अंतिम PHP5.3

यह global कीवर्ड के साथ असंभव है और आप भी सिर्फ $this उपयोग नहीं कर सकते में हटा दिया गया था। create_function के साथ फ़ंक्शन बॉडी को परिभाषित करते समय कक्षा से किसी संपत्ति का संदर्भ देने का कोई तरीका नहीं है।में

Fatal error: Using $this when not in object context 

इस
संक्षेप में आप एक समारोह वैश्विक क्षेत्र से एक चर का आयात बना सकते हैं

class A { 

    protected $prop = 'it works'; 

    public function test() 
    { 
     $fn = create_function('', 'echo $this->prop;'); 
     return $fn; 
    } 
} 

$a = new A; 
$fn = $a->test(); 
$fn(); 

परिणाम होगा, तो आप एक दायरे से एक चर का उपयोग नहीं कर नहीं बना सकते कर सकते हैं। और क्योंकि create_function का उपयोग करते समय तकनीकी रूप से बाध्यकारी नहीं होते हैं, लेकिन जब निर्मित फ़ंक्शन निष्पादित किया जाता है तो आयात करना, मैं पर बहस करना चाहता हूं, यह सीमा एक लैम्ब्डा को बंद कर देती है।


संपादित करें: नीचे ओनो मार्समैन द्वारा प्रदान किया गया समाधान काफी सभ्य है। यह क्लोजर को पूरी तरह से अनुकरण नहीं करता है, लेकिन कार्यान्वयन बहुत करीब है।

+2

यह वर्णन करने के लिए कोई शब्द नहीं है कि यह कितना भयानक है। (आपका उत्तर नहीं।) – ChaosPandion

+1

महान उत्तर! थम्स अप। – aefxx

3

मेरे समाधान: http://techblog.triptic.nl/simulating-closures-in-php-versions-prior-to-php-5-3/

हालांकि यह पहला तर्क के रूप में बंद करने के लिए किसी वस्तु में चर पारित करता है।

+0

कॉल करने के लिए बहुत अच्छा प्रयास() तकनीकी रूप से इसे मेरी राय में बंद करने के रूप में अयोग्य घोषित करता है (ठीक है, कम से कम कुछ हद तक)। इसके अलावा मुझे क्लोजर इंस्टेंस में पास करना होगा ताकि बंद ओवर वैरिएबल थोड़ा अजीब हो और call_user_func_array वापस आना चाहिए। लेकिन फिर भी, बहुत अच्छा है। क्या आपने क्लोजर क्लास 5.3 के बाद इसे मॉडल किया था? – Gordon

+0

मैंने पहले यह समाधान करने से पहले इस समाधान के बारे में सोचा था कि यहां तक ​​कि php 5.3 में एक आंतरिक क्लोजर क्लास भी मौजूद है। मुझे कॉल करने के लिए कॉल पसंद नहीं है() खुद और __invoke जादू विधि का उपयोग करेगा, केवल तभी जब यह php 5.3 तक उपलब्ध नहीं था ... –

+0

गॉर्डन: "call_user_func_array वापस लौटना चाहिए" के साथ क्या मतलब है? –

1

कुछ विशेष मामले हैं जहां आप इसे कर सकते हैं।

यदि आपको मान द्वारा एक वैरिएबल कैप्चर करने की आवश्यकता है (संदर्भ के अनुसार नहीं), और मान एक सामान्य मान प्रकार है जैसे उपरोक्त संख्या, स्ट्रिंग, या सरणी (वस्तुओं और संसाधनों और कार्यों जैसे संदर्भ प्रकार नहीं) तो आप बस var_export() का उपयोग कर समारोह परिभाषा में सम्मिलित कर सकते हैं:

$var = array(1, 3); 
$f = create_function('', 
    '$var=' . var_export($var,true) . '; return $var;'); 

आप समारोह की कॉल भर में परिवर्तनशील राज्य बनाए रखने के लिए संदर्भ द्वारा चर पर कब्जा करने की जरूरत है, लेकिन आप की जरूरत नहीं है परिवर्तन मूल दायरे में दिखाई देता है जहां यह बनाया गया है (उदाहरण के लिए एक संचयक बनाने के लिए, लेकिन योग में परिवर्तन को निर्माण क्षेत्र में योग चर बदलने की आवश्यकता नहीं है), तो आप इसे समान रूप से सम्मिलित कर सकते हैं, लेकिन एक स्थिर चर के रूप में:

function make_accumulator($sum) { 
    $f = create_function('$x', 
     'static $var=' . var_export($var,true) . '; return $var += $x;'); 
    return $f; 
} 
संबंधित मुद्दे