2011-01-17 13 views
8
--- A.php ---- 
require_once 'B.php'; 

class A 
{ 
    public function __constructor($x){...} 

    public function foo() 
    { 
     $b = B::getInstance(); 
     ... 
    } 
} 

--- B.php ---- 
require_once 'A.php'; 

class B extends A 
{ 
    protected static $_instance = null; 

    protected function __construct(){} 

    public static function getInstance() 
    {....} 
} 

पीएचपी बस जैसे ही यह लाइनसंरक्षक को संरक्षित या निजी के रूप में परिभाषित नहीं कर सकता! क्यूं कर?

protected function __construct(){} 

तक पहुँच जाता है और इससे पहले कि और कुछ भी नहीं है कि बाद में ब्राउज़र को भेज दिया गया होता सब कुछ आउटपुट कोड की व्याख्या बंद हो जाता है।

और जैसे ही मैं सिर्फ

के लिए बाहर है कि लाइन ले, उसे बदल कर
// protected function __construct(){} 

सब कुछ ठीक काम करता है !?

मुझे वह नहीं मिला।

कोई विचार?

+1

आप फ़ाइलों, जैसे में php उद्घाटन टैग है क्या वे ' Gordon

+1

__construct() विधि को सार्वजनिक होने की आवश्यकता होगी क्योंकि इसे कक्षा के उदाहरण के दौरान (सार्वजनिक रूप से) एक्सेस किया जाता है। –

+0

आपके छद्म कोड में कोई स्पष्ट समस्या नहीं है, इसलिए आपके वास्तविक कोड में समस्याएं सबसे अधिक संभावना हैं। यदि PHP चलना बंद कर देता है और कोई त्रुटि संदेश प्रदर्शित नहीं करता है, तो आपको शायद पूर्ण त्रुटि रिपोर्टिंग सक्षम करने की आवश्यकता है। यदि आप नहीं जानते हैं तो विवरण के लिए पूछने के लिए स्वतंत्र महसूस करें। –

उत्तर

12

मैंने अभी यह सुनिश्चित करने के लिए एक सरल परीक्षण फ़ाइल बनाई है कि यह मेरी मशीन पर भी होता है, और मुझे लगता है कि मुझे जवाब मिल गया है। "पीएचपी गंभीर त्रुटि::

<?php 
error_reporting(E_ALL | E_STRICT); 
class Foo { 
    public function __construct() { 
    } 
} 

class Bar extends Foo { 
    protected function __construct() { 
    } 
} 

जब कि कोड को निष्पादित करने की कोशिश कर रहा है, मैं एक गंभीर त्रुटि मिलती है: निम्नलिखित कोड ले लो एक्सेस का स्तर बार करने के लिए :: __ निर्माण() सार्वजनिक होना चाहिए (वर्ग फू के रूप में) में/लाइन 12 पर घर/बेरी/foo.php। " इसका मतलब है कि यदि आप माता-पिता पहले से ही पहुंच स्तर को परिभाषित कर चुके हैं, तो बच्चे वर्ग में पहुंच स्तर को नहीं बदला जा सकता है, जो वास्तव में बहुत समझ में आता है: PHP नहीं जानता कि किस कन्स्ट्रक्टर को कॉल करना है, मुझे लगता है।

एक साइड नोट के रूप में: अपने कोड को देखकर, बी ए बढ़ाता है, और ए बी का उपयोग करता है। ऐसा क्यों है, ऐसा लगता है कि यह मेरे लिए एक अजीब निर्माण है? मुझे लगता है कि आप वास्तव में composition, not inheritance चाहते हैं।

+0

हे बेरी, आपके उत्तर के लिए धन्यवाद। जैसा कि मैंने अपने जवाब में लिखा था, मुझे ए में संरक्षित तत्वों तक पहुंचने की आवश्यकता है और बी को सिंगलटन होने की आवश्यकता है। लेकिन यह कुछ हद तक अजीब बात है, "रिफैक्टरिंग-स्टेटस" के बी/सी का सामना करना पड़ रहा है। मुझे यकीन नहीं है कि अगर सबसे अच्छा विकल्प चुना गया है, लेकिन अब मुझे लगता है कि यह सबसे सरल होना चाहिए। – Raffael

+0

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

+0

मुझे लगता है कि यह बहस योग्य है कि PHP के लिए इस तरह से व्यवहार करने के लिए कितना अर्थ होता है (https://bugs.php.net/ देखें bug.php? id = 61,970)। लेकिन इसके लिए दिया गया आधिकारिक कारण लिस्कोव प्रतिस्थापन सिद्धांत है, जो मूल रूप से बताता है कि व्युत्पन्न कक्षाओं के उदाहरणों को "फिट" होना चाहिए जहां बेस क्लास इंस्टेंस की अपेक्षा की जाती है। – Peter

6

आप संरक्षक या निजी के रूप में एक निर्माता को परिभाषित कर सकते हैं। इस कोड को संकलितruns just fine since OOP was rewritten for PHP/5:

<?php 

class A{ 
    public function __construct(){ 
     echo 'Instance of A created' . PHP_EOL; 
    } 
} 

class B{ 
    protected function __construct(){ 
     echo 'Instance of B created' . PHP_EOL; 
    } 
} 

class C{ 
    private function __construct(){ 
     echo 'Instance of C created' . PHP_EOL; 
    } 
} 
बेशक

, निजी कंस्ट्रक्टर्स new कीवर्ड के साथ उदाहरण बनाकर करने से रोकने के लिए, लेकिन पीएचपी एक गंभीर त्रुटि (यह सिर्फ चल रहा बंद नहीं होगा) को गति प्रदान करेगा:

<?php 

new A; // OK 
new B; // Fatal error: Call to protected B::__construct() from invalid context 
new C; // Fatal error: Call to private C::__construct() from invalid context 
+1

बस चीजों को सीधे प्राप्त करने के लिए: वह कोड ठीक से संकलित नहीं होगा। उस कोड का अर्थ ठीक होगा;) –

+1

@ बेरी लेंजरक - मुझे * पता था * मेरा शब्द पसंद ध्रुवीय होगा :) –

+0

@ अलवारो जी। विकारियो: आपका शब्द पसंद 'ध्रुवीय' नहीं है, यह गलत है ... :-) – MarcoS

1

आप कस्टम स्थिर आरंभकर्ताओं बना सकते हैं:

<?php 

class FancyClass { 
    public static function init() { 
     new self(); 
    } 

    protected function __construct() { 
     echo 'Instance created!'; 
    } 
} 

# This will not work. 
new FancyClass(); 

# But this will work. 
FancyClass::init(); 
संबंधित मुद्दे

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