2010-02-23 14 views
5

के बीच साझा किया गया है, उदाहरण के दौरान ऑब्जेक्ट विधियों के अंदर परिभाषित स्थैतिक चर के साथ कुछ अनपेक्षित व्यवहार में आया है। यह शायद ज्ञात व्यवहार है, लेकिन जैसा कि मैं PHP दस्तावेज़ ब्राउज़ करता हूं, मुझे ऑब्जेक्ट विधियों के भीतर स्थैतिक रूप से परिभाषित चर के उदाहरण नहीं मिल सकते हैं। ,गैर-स्थैतिक विधि के भीतर स्थिर उदाहरण

<?php 

class Foo { 
    public function dofoo() { 
    static $i = 0; 
    echo $i++ . '<br>'; 
    } 
} 

$f = new Foo; 
$g = new Foo; 

$f->dofoo(); // expected 0, got 0 
$f->dofoo(); // expected 1, got 1 
$f->dofoo(); // expected 2, got 2 

$g->dofoo(); // expected 0, got 3 
$g->dofoo(); // expected 1, got 4 
$g->dofoo(); // expected 2, got 5 

अब मैं $i की उम्मीद है स्थिर उदाहरण प्रति होने के लिए होता है, लेकिन वास्तविकता में $i उदाहरणों के बीच साझा किया जाता है:

यहाँ व्यवहार की कमी मैं का सामना करना पड़ा है। अपने स्वयं के संपादन के लिए, क्या कोई इस बात का विस्तार कर सकता है कि यह मामला क्यों है, और जहां इसे php.net पर दस्तावेज किया गया है?

उत्तर

6

यह very definition स्थिर है।

आप सदस्यों एक वस्तु का एक उदाहरण के लिए विशिष्ट होना चाहते हैं, तो आप class properties

उदा का उपयोग करते हैं

<?php 

class Foo 
{ 
    protected $_count = 0; 
    public function doFoo() 
    { 
     echo $this->_count++, '<br>'; 
    } 
} 

संपादित करें: ठीक है, मैं OOP स्थिर गुणों के प्रलेखन जुड़े। अवधारणा हालांकि वही है। आप variable scope डॉक्स पढ़ें आप देखेंगे:

नोट: स्टेटिक घोषणाओं संकलन समय में हल कर रहे हैं।

इस प्रकार जब आपकी स्क्रिप्ट संकलित हो जाती है (इसे निष्पादित करने से पहले) स्थिर "सेटअप" होता है (सुनिश्चित नहीं है कि किस शब्द का उपयोग करना है)। इससे कोई फर्क नहीं पड़ता कि आप कितनी ऑब्जेक्ट्स को तत्काल बनाते हैं, जब वह फ़ंक्शन स्थैतिक चर संदर्भित होता है, वही प्रतिलिपि उसी कॉपी के रूप में होता है।

+0

वह दस्तावेज स्थैतिक वर्ग गुणों और विधियों के लिए है, एक विधि के भीतर स्थिर चर नहीं। –

+0

एडम: PHP5 में वे एक हैं और वही हैं। स्टेटिक स्थिर है। – hobodave

+0

मेरे दिमाग में, '$ f-> dofoo()' 'g g>> dofoo()' के समान विधि नहीं है। स्पष्ट है कि PHP डेवलपर्स एक ही दिमाग से नहीं हैं। :) –

1

यह स्थिर है, यह वर्ग के सभी उदाहरणों में एक ही चर है।

आप इसे लिखना चाहते हैं ताकि चर वर्ग के उदाहरण का एक निजी सदस्य हो।

class Foo { 
    private $i = 0; 
    public function dofoo() { 
    echo $this->i++ . '<br>'; 
    } 
} 
1

static मुख्य शब्द with variables इस्तेमाल किया जा सकता है, या with class methods and properties इस्तेमाल किया। PHP 4 में स्थिर चर प्रस्तुत किए गए थे (मुझे लगता है, यह पहले हो सकता है)। स्टेटिक वर्ग के सदस्यों/तरीकों, पीएचपी 5.

तो में पेश किए गए मार्गदर्शन के अनुसार, एक स्थिर चर

चर scoping का एक अन्य महत्वपूर्ण विशेषता स्थिर चर रहा है। एक स्थैतिक चर केवल स्थानीय फ़ंक्शन दायरे में मौजूद है, लेकिन जब प्रोग्राम निष्पादन इस दायरे को छोड़ देता है तो इसका मूल्य कम नहीं होता है।

यह आपके द्वारा वर्णित व्यवहार के अनुरूप है। यदि आप एक प्रति आवृत्ति चर चाहते हैं, तो नियमित वर्ग के सदस्य का उपयोग किया जाता है।

2

मैं मानता हूं कि वर्तमान PHP दस्तावेज बिल्कुल गैर-स्थैतिक विधि के अंदर एक स्थैतिक चर के लिए "स्कोप" का अर्थ स्पष्ट रूप से स्पष्ट नहीं है।

यह (hobodave इंगित करता है के रूप में) पाठ्यक्रम सच की है कि "स्थिर" आम तौर पर "वर्ग प्रति" का अर्थ है, लेकिन स्थिर वर्ग गुण एक (गैर स्थिर) विधि के भीतर बिल्कुल वही बात स्थिर के रूप में चर नहीं हैं, उसमें बाद में विधि द्वारा "स्कॉप्ड" किया जाता है (कक्षा में प्रत्येक विधि का अपना स्थिर $ foo चर हो सकता है, लेकिन $ foo नामक एक स्थिर वर्ग सदस्य में हो सकता है)।

और मैं तर्क है कि हालांकि PHP 5 व्यवहार संगत ("स्थिर" हमेशा का अर्थ है "वर्ग प्रति एक साझा उदाहरण"), यह नहीं है एक ही रास्ता है कि PHP सकता है व्यवहार है।

उदाहरण के लिए, अधिकांश लोग फ़ंक्शन कॉल में राज्य को बनाए रखने के लिए स्थैतिक फ़ंक्शन वेरिएबल्स का उपयोग करते हैं, और वैश्विक कार्यों के लिए PHP व्यवहार बिल्कुल वही है जो सभी उम्मीद करेंगे। इसलिए एक PHP दुभाषिया की कल्पना करना निश्चित रूप से संभव है जो विधिवत आमंत्रण में कुछ विधि चर के राज्य को बनाए रखता है और ऐसा "प्रति उदाहरण" करता है, और वास्तव में यह भी होता है कि मैंने पहली बार ऐसा करने की भी उम्मीद की कि मैंने स्थानीय विधि चर को स्थैतिक घोषित किया ।

0

7 साल तक यह लंबा समय लगता है लेकिन वैसे भी यह यहां जाता है।

सभी वर्गों में एक डिफ़ॉल्ट निर्माता है मैं यह क्यों कह रहा हूं?! क्योंकि यदि आप कन्स्ट्रक्टर में डिफ़ॉल्ट व्यवहार को परिभाषित करते हैं तो कक्षा के प्रत्येक उदाहरण प्रभावित होंगे।

उदाहरण:

namespace Statics; 

class Foo 
{ 
    protected static $_count; 

    public function Bar() 
    { 
     return self::$_count++; 
    } 

    public function __construct() 
    { 
     self::$_count = 0; 
    } 
} 

में परिणामी:

require 'Foo.php'; 

use Statics\Foo; 

$bar = new Foo(); 
echo $bar->bar().'<br>'; 
echo $bar->bar().'<br>'; 
echo $bar->bar().'<br>'; 

$barcode = new Foo(); 
echo $barcode->bar().'<br>'; 
echo $barcode->bar().'<br>'; 
echo $barcode->bar().'<br>'; 

0 
1 
2 
0 
1 
2 

उच्च वर्ग से हर नया उदाहरण 0 से शुरू कर देंगे! स्थिर गणना व्यवहार कई उदाहरणों में साझा नहीं किया जाएगा क्योंकि यह निर्माता में निर्दिष्ट मूल्य से शुरू होगा।

यदि आपको कई उदाहरणों में डेटा साझा करने की आवश्यकता है, तो आपको एक स्थिर चर परिभाषित करना और कन्स्ट्रक्टर के बाहर डिफ़ॉल्ट डेटा असाइन करना है!

उदाहरण:

namespace Statics; 

class Foo 
{ 
    //default value 
    protected static $_count = 0; 

    public function Bar() 
    { 
     return self::$_count++; 
    } 

    public function __construct() 
    { 
     //do something else 
    } 
} 

में परिणामी:

require 'Foo.php'; 

use Statics\Foo; 

$bar = new Foo(); 
echo $bar->bar().'<br>'; 
echo $bar->bar().'<br>'; 
echo $bar->bar().'<br>'; 

$barcode = new Foo(); 
echo $barcode->bar().'<br>'; 
echo $barcode->bar().'<br>'; 
echo $barcode->bar().'<br>'; 

0 
1 
2 
3 
4 
5 

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

मुझे आशा है कि इससे मदद मिलेगी, न कि उपरोक्त उत्तरों गलत हैं लेकिन मुझे लगा कि इस कोण से सभी अवधारणाओं को समझना महत्वपूर्ण था।

पुर्तगाल से सम्मान!

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