2010-03-13 7 views
14
class t { 
    public function tt() 
    { 
     echo 1; 
    } 
} 
t::tt(); 

देखें? गैर-स्थैतिक फ़ंक्शन को कक्षा स्तर पर भी बुलाया जा सकता है। तो public से पहले static कीवर्ड जोड़ने पर क्या अलग है?क्या PHP में स्थिर विधि में गैर स्थैतिक विधि के साथ कोई अंतर है?

+5

वाह, यह वास्तव में काम करता है। PHP वास्तव में एक गड़बड़ है। – Gumbo

+0

@ गम्बो: PHP4 बैककंपेट, यदि आप इसे सख्त पसंद करते हैं, तो सख्त त्रुटियों पर अपवाद फेंक दें। – hakre

उत्तर

14
कि सिवाय

, यदि आप अपने विधि में $this उपयोग करने के लिए, इस तरह का प्रयास करें:

Fatal error: Using $this when not in object context in ...\temp.php on line 11 

:

class t { 
    protected $a = 10; 
    public function tt() { 
     echo $this->a; 
     echo 1; 
    } 
} 
t::tt(); 

आप जब गैर स्थैतिक विधि स्थिर बुला एक घातक त्रुटि मिल जाएगा यानी आपका उदाहरण थोड़ा बहुत आसान है, और वास्तव में वास्तविक मामले के अनुरूप नहीं है ;-)


भी ध्यान रखें कि आपके उदाहरण आप एक सख्त चेतावनी (quoting) मिलना चाहिए:

कॉलिंग गैर स्थिर तरीकों स्थिर एक E_STRICT स्तर चेतावनी उत्पन्न करता है।

और यह वास्तव में करता है (कम से कम, पीएचपी 5.3 के साथ):

Strict Standards: Non-static method t::tt() should not be called statically in ...\temp.php on line 12 
1 

तो: कि अच्छा, ;-)


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


एक बार फिर भले ही पीएचपी आप कुछ (हो सकता है कि ऐतिहासिक कारणों के लिए - पुराने संस्करणों के साथ की तरह अनुकूलता) करने की अनुमति देता, इसका मतलब यह नहीं है कि आप यह करना चाहिए!

+0

मुझे सख्त चेतावनी नहीं मिली, php.ini सेटिंग 'error_reporting = E_ALL' – user198729

+3

@user: ऐसा इसलिए है क्योंकि' E_ALL' में 'E_STRICT' शामिल नहीं है - देखें http://www.php.net/ मैन्युअल/en/errorfunc.constants.php जो बताता है कि 'E_ALL' है * "समर्थित सभी त्रुटियों और चेतावनियों, PHP में स्तर' E_STRICT' को छोड़कर <6 "* –

+0

ओह, मैं' error_reporting = E_ALL में बदल गया हूं और E_STRICT', अभी भी कोई चेतावनी नहीं .. PHHP5.3.0 – user198729

4

Static Keyword

क्योंकि स्थिर तरीकों बनाया वस्तु का एक उदाहरण के बिना प्रतिदेय हैं, छद्म चर $ इस विधि स्थिर के रूप में घोषित अंदर उपलब्ध नहीं है।

तीर ऑपरेटर -> का उपयोग कर ऑब्जेक्ट के माध्यम से स्टेटिक गुणों तक पहुंचा नहीं जा सकता है।

गैर-स्थैतिक विधियों को कॉल करना स्थिर रूप से एक ई_स्ट्रिक्ट स्तर चेतावनी उत्पन्न करता है।

सिर्फ इसलिए कि आप गैर स्थैतिक तरीकों को स्थिर रूप से कॉल कर सकते हैं इसका मतलब यह नहीं है कि आपको चाहिए। यह बुरा फॉर्म है।

2

सामान्य एक स्थिर विधि में भी वर्ग विधि कहा जाता है जबकि एक गैर स्थैतिक विधि भी वस्तु विधि या उदाहरण विधि कहा जाता है।

कक्षा विधि और ऑब्जेक्ट विधि के बीच का अंतर यह है कि कक्षा विधियां केवल वर्ग गुणों (स्थिर गुणों) तक पहुंच सकती हैं जबकि ऑब्जेक्ट विधियों का उपयोग ऑब्जेक्ट गुणों (समान वर्ग उदाहरण के गुणों) तक पहुंचने के लिए किया जाता है।

स्थिर डेटा और गुणों का उपयोग सामान्य डेटा को उस विशिष्ट वर्ग के सभी उदाहरणों के लिए साझा करने के लिए किया जाता है।

class A { 
    private static $counter = 0; 

    public function __construct() { 
     self::counter = self::counter + 1; 
    } 

    public function __destruct() { 
     self::counter = self::counter - 1; 
    } 

    public static function printCounter() { 
     echo "There are currently ".self::counter." instances of ".__CLASS__; 
    } 
} 

$a1 = new A(); 
$a2 = new A(); 
A::printCounter(); 
unset($a2); 
A::printCounter(); 

ध्यान दें कि स्थिर संपत्ति काउंटर निजी इसलिए यह केवल वर्ग अपने आप में पहुँचा जा सकता है है:

आप, उदाहरण के लिए, एक स्थिर संपत्ति उदाहरणों की संख्या का ट्रैक रखने के इस्तेमाल कर सकते हैं और उस वर्ग के उदाहरण लेकिन बाहर से नहीं।

1

एक मुख्य अंतर यह है कि उल्लेख नहीं किया गया है बहुरूपी व्यवहार से संबंधित है।

गैर स्थैतिक विधियों, जब एक व्युत्पन्न कक्षा में पुनर्वित्त, बेस क्लास विधि को ओवरराइड करते हैं, और उन उदाहरणों के आधार पर पॉलिमॉर्फिक व्यवहार की अनुमति देते हैं जिन्हें वे बुलाया जाता है। यह स्थैतिक तरीकों के मामले में नहीं है


पीएचपी 5.3 जो स्थिर विरासत के संदर्भ में कहा जाता वर्ग संदर्भ के लिए इस्तेमाल किया जा सकता late static binding की अवधारणा प्रस्तुत की।

0

हां, महत्वपूर्ण अंतर यह है कि static घोषित विधियों को ऑब्जेक्ट-संदर्भ चर, $this तक पहुंच नहीं है।

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

इसके अलावा, किसी ऑब्जेक्ट संदर्भ में नहीं होने पर $this को संदर्भित करने का कोई भी प्रयास E_ERROR ईवेंट ट्रिगर करेगा।

<?php 
error_reporting(-1); 
//error_reporting(E_ALL); 

class DualNature { 
    public static function fnStatic() { 
    if (isset($this)) { 
     // never ever gets here 
     $myValue = $this->_instanceValue; 
    } else { 
     // always gets here 
     $myValue = self::$_staticValue; 
    } 
    return $myValue; 
    } 

    public function fnInstance() { 
    if (isset($this)) { 
     // gets here on instance (->) reference only 
     $myValue = $this->_instanceValue; 
    } else { 
     // gets here in all other situations 
     $myValue = self::$_staticValue; 
    } 
    return $myValue; 
    } 

    public static function fnStaticDeath() { 
    return $this->_instanceValue; 
    } 

    private static $_staticValue = 'no access to $this'; 
    private $_instanceValue = '$this is available'; 

} 

$thing = new DualNature(); 
echo "==========\n"; 
printf("DualNature::fnStatic(): \"%s\"\n", DualNature::fnStatic()); 
echo "==========\n"; 
printf("\$thing::fnStatic(): \"%s\"\n", $thing::fnStatic()); 
echo "==========\n"; 
printf("\$thing->fnStatic(): \"%s\"\n", $thing->fnStatic()); 
echo "==========\n"; 
printf("DualNature::fnInstance(): \"%s\"\n", DualNature::fnInstance()); 
echo "==========\n"; 
printf("\$thing::fnInstance(): \"%s\"\n", $thing::fnInstance()); 
echo "==========\n"; 
printf("\$thing->fnInstance(): \"%s\"\n", $thing->fnInstance()); 
echo "==========\n"; 
printf("\$thing->fnStaticDeath(): \"%s\"\n", $thing->fnStaticDeath()); 
echo "==========\n"; 
echo "I'M ALIVE!!!\n"; 

ऊपर के उत्पादन में है:

========== 
PHP Strict Standards: Non-static method DualNature::fnInstance() should not be called statically in example.php on line 45 
DualNature::fnStatic(): "no access to $this" 
========== 
$thing::fnStatic(): "no access to $this" 
========== 
$thing->fnStatic(): "no access to $this" 
PHP Strict Standards: Non-static method DualNature::fnInstance() should not be called statically in example.php on line 47 
========== 
DualNature::fnInstance(): "no access to $this" 
========== 
$thing::fnInstance(): "no access to $this" 
========== 
$thing->fnInstance(): "$this is available" 
========== 
PHP Fatal error: Using $this when not in object context in example.php on line 29 
है कि घटना के व्यवहार उत्पादन के लिए त्रुटि लॉग (या STDERR) के लिए एक संदेश और स्थिति 255

साथ कार्यक्रम बाहर निकलने के लिए उदाहरण के लिए है

त्रुटि रिपोर्टिंग स्तर को E_ALL में बदलना डिफ़ॉल्ट E_STRICT चेतावनी संदेशों को दबाएगा (ईवेंट अभी भी प्रचारित होगा), लेकिन $this का अमान्य संदर्भ अभी भी एक घातक त्रुटि का कारण बन जाएगा और प्रोग्राम से बाहर निकल जाएगा।

0

वाक्यविन्यास और कार्यात्मक मतभेदों के अलावा एक प्रदर्शन अंतर भी महत्वपूर्ण है।

आप इसे कम से कम विस्तृत comparison of static and non-static methods in PHP देख सकते हैं।