2010-04-09 12 views
8

तो, अगर आप इस तरह एक नेस्टेड वर्ग करने की कोशिश:PHP नेस्टेड कक्षाएं काम ... तरह का?

//nestedtest.php 

class nestedTest{ 
    function test(){ 
     class E extends Exception{} 
     throw new E; 
    } 
} 

आपको एक त्रुटि Fatal error: Class declarations may not be nested in [...]

मिल जाएगा, लेकिन आप तो जैसे एक अलग फ़ाइल में एक वर्ग है, तो:

//nestedtest2.php 

class nestedTest2{ 
    function test(){ 
     include('e.php'); 
     throw new E; 
    } 
} 

//e.php 
class E Extends Exception{} 

तो, ऐसा करने का दूसरा हैकी तरीका क्यों काम करता है, लेकिन ऐसा करने का गैर-हैकी तरीका काम नहीं करता है?

उत्तर

18

पुस्तिका (http://php.net/manual/en/function.include.php) से:

जब एक फ़ाइल शामिल है, कोड यह शामिल लाइन के चर गुंजाइश जो द शामिल होता इनहेरिट करती है। पर उपलब्ध कोई भी वेरिएबल से आगे की ओर जाने वाली फ़ाइल के भीतर उपलब्ध होगा। हालांकि, में परिभाषित कार्यों और वर्गों में फ़ाइल का वैश्विक दायरा है।

+1

+1 को पता नहीं था कि – soulmerge

+0

तो, उनके पास वैश्विक दायरा है, और मैं सभी को कॉल कर सकता हूं निजी और संरक्षित कार्यों में कक्षा है ... – SeanJA

+0

@ सेनजा: क्योंकि उनके पास वैश्विक दायरा है, आप कक्षा के उन गैर-सार्वजनिक तरीकों को कॉल करने में सक्षम नहीं होंगे जिनमें शामिल हैं() –

1

दूसरा तरीका कक्षाओं के घोंसले नहीं है। आपके पास सिर्फ एक ही फाइल में दोनों घोषणाएं हैं, जो आपके पहले उदाहरण से अलग हैं। PHP में आप एक फ़ाइल में एकाधिक कक्षा घोषणाएं कर सकते हैं, यह एक संगठनात्मक निर्णय नहीं है।

+1

फिर भी, उसके पास एक बिंदु है: वह एक समारोह के भीतर कोड शामिल कर रहा है। –

+1

@ पेक्का यह कामों को शामिल करने के कारण है: * जब कोई फ़ाइल शामिल होती है, तो उस कोड में उस रेखा के चरणीय दायरे को प्राप्त होता है जिसमें शामिल होता है। कॉलिंग फ़ाइल में उस लाइन पर उपलब्ध कोई भी चर उस बिंदु से आगे की फ़ाइल के भीतर उपलब्ध होगा। हालांकि, शामिल फ़ाइल में परिभाषित सभी कार्यों और वर्गों में वैश्विक दायरा है। * Http://de3.php.net/manual/en/function.include.php – Gordon

+1

कोई फर्क नहीं पड़ता क्योंकि वे एक ही फ़ाइल में हैं। वह अपवाद वर्ग को किसी अन्य फ़ाइल में डालने और इसे शामिल करने या __autoload का उपयोग करने के साथ समान प्रभाव प्राप्त कर सकता है। –

1

किसी विधि के अंदर कक्षा को परिभाषित करने का कोई अच्छा कारण नहीं है। दूसरा तरीका केवल इस अर्थ में "काम करता है" कि यह कोई त्रुटि नहीं फेंकता है - कक्षा अभी भी एक ही दायरे/नामस्थान में अन्य सभी परिभाषित वर्गों के रूप में मौजूद है। तो, आप वास्तव में इस परिदृश्य में एक वर्ग "घोंसला" नहीं कर रहे हैं।

वैसे, इसका कारण यह है कि एक वर्ग केवल एक परिभाषा है - कक्षा को परिभाषित करने में कोई निष्पादन नहीं है। इसलिए फ़ाइल (e.php) जैसे ही आप इसे शामिल करते हैं, विश्लेषण किया जाता है, और फिर इसकी कक्षा वर्तमान निष्पादन संदर्भ में उपलब्ध हो जाती है। कोड के केवल निष्पादन योग्य भाग (यानी, throw new E;) वास्तव में कॉलर के दायरे से संबंधित होंगे।

+0

यह वास्तव में आया क्योंकि मैं चिंतित था कि दूसरा तरीका काम नहीं करेगा क्योंकि पहला तरीका नहीं है ... जब ऐसा हुआ, तो मैं थोड़ा परेशान था। – SeanJA

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