2012-12-08 36 views
10

मेरे पास एक बेस क्लास है जिसे मुझे कक्षा में संदर्भित कक्षा में कार्यों को कॉल करने की आवश्यकता है।अभिभावक वर्ग से बाल वर्ग स्थिर चर का उपयोग करें?

आसान पर्याप्त,

class base_class { 

    public function doSomethingWithReference(){ 
     $this->reference->doSomething(); 
    } 
} 

class extended_class extends base_class{ 

    protected $reference; 

    public function __construct($ref){ 
     $this->reference = $ref; 
    } 
} 

अब इस ठीक जाहिर है काम करता है,

लेकिन, जब मैं मैं $this->reference

का मूल्य लेकिन, उद्देश्य यह है कि $this->reference के बारे में परवाह नहीं है डिबगिंग हूँ इसका मतलब है विशाल है!

इसलिए, जब मैं print_r($instanceOfExtendedClass) करता हूं तो मुझे उस ऑब्जेक्ट का प्रिंट आउट मिलता है।

अब प्रत्येक वर्ग के लिए संदर्भ अलग है जो base_class बढ़ाता है।

मैं जो करना चाहता था वह extended_class कक्षा पर एक स्थिर संपत्ति के रूप में बस reference सेट करना था।

लेकिन फिर doSomethingWithReferenceself::$reference बदलना एक अपरिभाषित चर त्रुटि को फेंकता है।

और base_class में स्थिर चर सेट करने और extended_class से इसे संशोधित करने से यह काम नहीं करता है क्योंकि यह उस वर्ग से फैली सभी चीज़ों के लिए चर बदलता है।

क्या ऐसा करने का कोई तरीका है इसलिए मुझे $this->reference का प्रिंट आउट नहीं मिला है?

+2

आप किस PHP संस्करण के साथ काम कर रहे हैं? 5.3 में 'स्थिर' व्यवहार में कुछ [* बड़े * परिवर्तन थे] (http://php.net/language.oop5.late-static- बाइंडिंग), और यह जानकर कि क्या आप किसी पुराने चीज़ पर फंस गए हैं, आपको एक बहुत अलग जवाब। – Charles

+1

PHP संस्करण 5.3 – Hailwood

+0

यह वर्ग संरचना कुछ का उल्लंघन करती है, मुझे यकीन नहीं है कि यह क्या है :) –

उत्तर

14

क्योंकि आप PHP 5.3 का उपयोग कर रहे हैं, तो आप क्रम में सही कक्षा में स्थिर कॉल को हल करने late static binding उपयोग कर सकते हैं।

class base_class { 

    public function doSomethingWithReference(){ 
     static::$reference->doSomething(); 
    } 

} 

class extended_class extends base_class{ 

    protected static $reference; 

    public function __construct($ref){ 
     static::$reference = $ref; 
    } 

} 

बिग वसा अनुस्मारक: एक extended_class::$referenceextended_class उदाहरणों के सभी के बीच साझा किया जा रहा है यही कारण है कि। यदि वह नहीं है जो आप चाहते हैं, यह काम नहीं करेगा।

आप वास्तव में स्मृति या संसाधन उपयोग के बारे में चिंतित हैं। PHP में, सभी वस्तुओं संदर्भ द्वारा पारित कर रहे हैं। इसका मतलब यह है कि किसी ऑब्जेक्ट को तर्क के रूप में पास करना, या इसकी प्रतिलिपि बनाना आदि अतिरिक्त स्मृति का उपभोग नहीं करता है। यदि आपको किसी अन्य ऑब्जेक्ट में किसी ऑब्जेक्ट को संदर्भित करने की आवश्यकता है, तो ऐसा करने से अतिरिक्त मेमोरी का उपभोग नहीं करेगा।


अगर मैं extended_class और एक अन्य समान वर्ग था (जैसे कि extended_class1) वे संदर्भ के रूप में अच्छी तरह से साझा करेंगे? या सभी विस्तारित_क्लास 'उदाहरण एक संदर्भ साझा करेंगे, जबकि सभी विस्तारित_क्लास 1' उदाहरण एक और (आदर्श मामला) साझा करेंगे?

ऐसा लगता है कि साझाकरण स्थिर चर परिभाषित किया गया है।दो उदाहरणों में शामिल दोनों पीएचपी इंटरैक्टिव शीघ्र से:

php > class Shared { public $me; public function __construct($me) { $this->me = $me; } } 
php > class Base { protected static $ref; public function foo() { echo static::$ref->me, "\n"; } } 
php > class Inherit_1 extends Base { public function __construct($ref) { static::$ref = $ref; } } 
php > class Inherit_2 extends Base { public function __construct($ref) { static::$ref = $ref; } } 
php > class Inherit_3 extends Inherit_1 {} 
php > $shared_1 = new Shared(1) 
php > ; 
php > $shared_2 = new Shared(2); 
php > $shared_3 = new Shared(3); 
php > 
php > $in_1 = new Inherit_1($shared_1); 
php > $in_2 = new Inherit_2($shared_2); 
php > $in_3 = new Inherit_3($shared_3); 
php > 
php > $in_1->foo(); 
3 
php > $in_2->foo(); 
3 
php > $in_3->foo(); 
3 

इस मामले में, क्योंकि आधार वर्ग में संदर्भ रहता है, आप सभी को समान देखता है। मुझे लगता है कि यह किसी तरह का अर्थ बनाता है।

क्या होता है जब हम प्रत्येक बच्चे वर्ग के साथ संदर्भ घोषित करते हैं .. अधिकांश समय?

php > class Shared { public $me; public function __construct($me) { $this->me = $me; } } 
php > class Base { public function foo() { echo static::$ref->me, "\n"; } } 
php > class Inherit_1 extends Base { protected static $ref; public function __construct($ref) { static::$ref = $ref; } } 
php > class Inherit_2 extends Base { protected static $ref; public function __construct($ref) { static::$ref = $ref; } } 
php > class Inherit_3 extends Inherit_1 {} 
php > class Inherit_4 extends Inherit_1 { protected static $ref; } 
php > $shared_1 = new Shared(1); 
php > $shared_2 = new Shared(2); 
php > $shared_3 = new Shared(3); 
php > $shared_4 = new Shared(4); 
php > $in_1 = new Inherit_1($shared_1); 
php > $in_2 = new Inherit_2($shared_2); 
php > $in_3 = new Inherit_3($shared_3); 
php > $in_4 = new Inherit_4($shared_4); 
php > $in_1->foo(); 
3 
php > $in_2->foo(); 
2 
php > $in_3->foo(); 
3 
php > $in_4->foo(); 
4 

क्योंकि 3 अपनी स्थिर संपत्ति घोषित किए बिना 1 से विरासत में मिला है, इसे 1 का विरासत मिला है। जब हम 3 को साझा (3) पर सेट करते हैं, तो यह 1 के मौजूदा साझा (1) को ओवरराइट करता है।

निष्कर्ष: इस काम के लिए, संपत्ति को प्रत्येक कक्षा में घोषित करने की आवश्यकता है जिसे एकल अद्वितीय संदर्भ की आवश्यकता है। ध्यान दें कि यह कोड 5.4.x के रूप में मान्य है।

+0

मैं वास्तव में स्मृति के बारे में चिंतित नहीं हूं, यह केवल डिबगिंग के लिए है, मुझे यह देखने के लिए ~ 600 लाइनें (कोड इग्निटर ऑब्जेक्ट्स!) स्क्रॉल करना पसंद नहीं है, यह देखने के लिए कि ऑब्जेक्ट गुण क्या हैं! संदर्भों को साझा करने के लिए 'विस्तारित_क्लास :: $ संदर्भ' के बारे में आपका बिंदु, यदि मेरे पास 'expand_class' और एक और समान वर्ग (' expand_class1' कहें) तो क्या वे संदर्भ भी साझा करेंगे? या सभी 'विस्तारित_क्लास' उदाहरण एक संदर्भ साझा करेंगे, जबकि सभी 'विस्तारित_क्लास 1' 'उदाहरण एक और (आदर्श मामला) साझा करेंगे? – Hailwood

+0

@ हैलवुड, मैंने एक परीक्षण के साथ अपना जवाब अपडेट किया है जिसमें स्थिर संपत्ति का समाधान किया गया है। – Charles

2

स्थिर बच्चे के सदस्य तक पहुँचने के लिए माता-पिता के लिए एक तरह से प्रदान करें:

<?php 

abstract class base_class { 
    abstract protected function reference(); 
    // If you want to be able to instanciate base class directly, use the following 2 lines in place of the previous 2 lines: 
//class base_class { 
    //protected function reference() {} 

    public function doSomethingWithReference(){ 
     $this->reference()->doSomething(); 
    } 
} 

class extended_class extends base_class{ 
    protected static $reference; 

    public function __construct($ref){ 
     self::$reference = $ref; 
    } 

    protected function reference(){ 
     return self::$reference; 
    } 
} 

class ref { 
    public function doSomething(){ 
     echo __METHOD__; 
    } 
} 

$ref = new ref(); 
$ec = new extended_class($ref); 
$ec->doSomethingWithReference(); 

print_r($ec); 
?> 
+2

-1, यह सिर्फ एक कोड डंप है। आपने यह समझाया नहीं है कि यह कोड क्या है, यह क्यों काम करता है, यह कैसे काम करता है, और यह प्रश्न का उत्तर कैसे देता है। – Charles

+2

आलोचना के लिए धन्यवाद, @ चार्ल्स - कोई कटाक्ष इरादा नहीं है। वास्तव में, आपकी टिप्पणी के लिए +1। भविष्य में, मैं अधिक वर्बोज़ होने के लिए निश्चित रहूंगा और यह नहीं मानूंगा कि पाठक समझ जाएगा कि कोड पढ़कर क्या हो रहा है। मेरे पास PHP <5.3 आसान वाला बॉक्स नहीं है, लेकिन मेरा मानना ​​है कि यह उदाहरण उन लोगों के लिए काम करेगा जो देर से स्थिर बाइंडिंग के बिना फंस गए हैं। एक बार जब मैं पुष्टि करता हूं कि यह कम संस्करणों में काम करता है, तो मैं whys और hows को समझाने के लिए अपना उत्तर अपडेट कर दूंगा, और यह बताता हूं कि इस उत्तर का PHP <5.3 के उपयोगकर्ताओं के लिए मूल्य है। –