एक कक्षा के अंदर एक स्थिर विधि कहते हैं?


166

मैं उसी कक्षा के अंदर किसी अन्य विधि से एक स्थिर विधि कैसे कह सकता हूं?

$this->staticMethod();

या

$this::staticMethod();

13
आपको इसमें रुचि हो सकती है ( selfबनाम $this): stackoverflow.com/questions/151969/php-self-vs-this
फेलिक्स क्लिंग

सिर्फ एक FYI करें, आपका पहला उदाहरण एक स्थिर चर को कॉल करने वाला एक उदाहरण चर है, जो संभव नहीं है क्योंकि एक स्थिर विधि वर्ग का हिस्सा है और उदाहरण चर के माध्यम से सुलभ नहीं है।
जोजेसन

यदि आप केवल स्थैतिक विधियों का उपयोग कर रहे हैं और कोई उदाहरण मौजूद नहीं है तो कृपया इसे $ हटा सकते हैं।
मल्हल

जवाबों:


322

...लेकिन क्यों? $ यह-> staticMethod () भी काम करता है। क्या आप यह समझा सकते हैं कि स्वयं :: staticMethod () अधिक सही है (यदि यह है)?
इयान डन

29
@ इयान डन पुट बस, $thisकेवल तभी मौजूद होता है जब किसी ऑब्जेक्ट को तत्काल किया गया हो और आप केवल $this->methodकिसी मौजूदा ऑब्जेक्ट के भीतर से ही उपयोग कर सकते हैं । यदि आपके पास कोई वस्तु नहीं है, लेकिन केवल एक स्थिर विधि को कॉल करें और उस विधि में आप उसी कक्षा में एक और स्थिर विधि को कॉल करना चाहते हैं, तो आपको उपयोग करना होगा self::। तो संभावित त्रुटियों (और सख्त चेतावनियों) से बचने के लिए इसका उपयोग करना बेहतर है self
12 को जीरो

1
धन्यवाद! लारवल में, मैंने पाया कि मैं गलती से एक विस्तारित नियंत्रक का उपयोग करके स्थिर विधि को कॉल कर रहा था $this, लेकिन कोड को धकेलने तक समस्या नहीं हुई stage। कोई त्रुटि नहीं आई, मूल्य बस था 0। इस, उपयोग के साथ सावधान रहनाself::
blamb

44

मान लें कि यह आपकी कक्षा है:

class Test
{
    private $baz = 1;

    public function foo() { ... }

    public function bar() 
    {
        printf("baz = %d\n", $this->baz);
    }

    public static function staticMethod() { echo "static method\n"; }
}

foo()विधि के भीतर , आइए विभिन्न विकल्पों को देखें:

$this->staticMethod();

ताकि staticMethod()एक उदाहरण विधि के रूप में कॉल , सही? ऐसा नहीं होता। ऐसा इसलिए है क्योंकि विधि को घोषित किया public staticगया है क्योंकि दुभाषिया इसे एक स्थिर विधि के रूप में कहेगा, इसलिए यह अपेक्षा के अनुरूप काम करेगा। यह तर्क दिया जा सकता है कि ऐसा करने से कोड से कम स्पष्ट होता है कि एक स्थिर विधि कॉल हो रही है।

$this::staticMethod();

PHP 5.3 के बाद से आप $var::method()अर्थ के लिए उपयोग कर सकते हैं <class-of-$var>::; यह काफी सुविधाजनक है, हालांकि उपरोक्त उपयोग-मामला अभी भी अपरंपरागत है। तो यह हमें स्थैतिक विधि को कॉल करने के सबसे सामान्य तरीके से लाता है:

self::staticMethod();

अब, इससे पहले कि आप यह सोच कर कि शुरू ::है स्थिर कॉल ऑपरेटर, मैं आपको एक और उदाहरण देता है:

self::bar();

यह प्रिंट होगा baz = 1, जिसका अर्थ है कि $this->bar()और self::bar()बिल्कुल वही काम करना; ऐसा इसलिए ::है क्योंकि सिर्फ एक गुंजाइश रिज़ॉल्यूशन ऑपरेटर है। यह वहाँ बनाने के लिए है parent::, self::और static::काम करते हैं और आप स्थिर चर तक पहुँच प्रदान करते हैं; एक विधि को कैसे कहा जाता है यह उसके हस्ताक्षर पर निर्भर करता है और कॉल करने वाले को कैसे बुलाया गया था।

इस क्रिया को देखने के लिए, यह 3v4l.org आउटपुट देखें ।


self::bar()भ्रामक लगता है - कि अब पदावनत हो गया है? ( self::एक स्थिर विधि के बजाय एक इंस्टेंस विधि का उपयोग करने के लिए)।
ToolmakerSteve

@ToolmakerSteve किस तरीके से आप कहेंगे कि यह भ्रामक है?
16

तार्किक रूप से, selfस्थैतिक पद्धति को लागू करते समय कोई बात नहीं है । परिभाषा के अनुसार: स्थैतिक विधि कहीं से भी कॉल करने योग्य है, और "स्वयं" पैरामीटर प्राप्त नहीं करता है। फिर भी, मैं उस phpवाक्य रचना की सुविधा देखता हूं , ताकि आपको लिखना न पड़े MyClassName::। मुझे सांख्यिकीय रूप से टाइप की जाने वाली भाषाओं में उपयोग किया जाता है, जहां कंपाइलर को मौजूदा दायरे में उपलब्ध सभी वेरिएबल्स दिए जाने हैं, इसलिए (इसके बराबर) self::छोड़ा जा सकता है। तो एक ने ही कहा self instanceMethod; कहने का कोई कारण नहीं self staticMethod
टूलमेकरसिटेव

15

यह एक बहुत देर से प्रतिक्रिया है, लेकिन पिछले उत्तरों पर कुछ विवरण जोड़ता है

जब एक ही क्लास में दूसरे स्टैटिक मेथड से PHP में स्टेटिक तरीके से कॉल करने की बात आती है, तो selfक्लास के नाम के बीच अंतर करना जरूरी है ।

उदाहरण के लिए इस कोड को लें:

class static_test_class {
    public static function test() {
        echo "Original class\n";
    }

    public static function run($use_self) {
        if($use_self) {
            self::test();
        } else {
            $class = get_called_class();
            $class::test(); 
        }
    }
}

class extended_static_test_class extends static_test_class {
    public static function test() {
        echo "Extended class\n";
    }
}

extended_static_test_class::run(true);
extended_static_test_class::run(false);

इस कोड का आउटपुट है:

मूल वर्ग

विस्तारित वर्ग

इसका कारण यह है कि selfजिस वर्ग को कोड कहा जा रहा है, उस वर्ग के बजाय यह उस कोड से संबंधित है, जहां से इसे बुलाया जा रहा है।

यदि आप एक वर्ग पर परिभाषित विधि का उपयोग करना चाहते हैं जो मूल वर्ग को विरासत में मिला है, तो आपको कुछ इस तरह का उपयोग करने की आवश्यकता है:

$class = get_called_class();
$class::function_name(); 

2
मुझे यह जानकारीपूर्ण लगी। एक छोटा सा नाइट, मैं यह नहीं कहूंगा कि अन्य उत्तर "भ्रामक" हैं। अधिक सटीक कहने के लिए कि वे "अपूर्ण" हैं; वे self::(दुर्लभ) मामले में क्या करता है (अनकैप्ड) प्रश्न को संबोधित नहीं करते हैं जहां एक स्थैतिक विधि A किसी अन्य स्थैतिक विधि को कॉल करती है, और B को उप-वर्ग में ओवरराइड किया गया है। IMHO, यह "उदाहरण" के तरीकों से ओवरराइडिंग विधि को प्रतिबंधित करने के लिए कम भ्रमित नहीं है; स्थैतिक स्तर पर संयम से उस क्षमता का उपयोग करें। इसे दूसरे तरीके से डालें, आपके कोड के पाठक इंस्टेंस मेथड्स (जो कि OO कोडिंग का सार है) की अपेक्षा करते हैं, लेकिन स्टैटिक वाले नहीं।
टूलमेकरस्टेव

1
बहुत मददगार और यह समझ में आता है कि वर्ग का विस्तार मूल वर्ग नहीं है। इसलिए यह कारण है कि selfउस मामले में इस्तेमाल नहीं किया जाएगा। आपने प्रथम श्रेणी के विस्तार के रूप में एक अलग वर्ग घोषित किया है। selfविस्तारित वर्ग के भीतर का उपयोग विस्तारित वर्ग को संदर्भित करेगा। यह अन्य उत्तरों का खंडन नहीं करता है, लेकिन यह निश्चित रूप से इसके दायरे को प्रदर्शित करने में मदद करता है self
इयरिन

2

बाद के PHP संस्करण में self::staticMethod();भी काम नहीं करेगा। यह सख्त मानक त्रुटि को फेंक देगा।

इस मामले में, हम एक ही वर्ग के ऑब्जेक्ट बना सकते हैं और ऑब्जेक्ट द्वारा कॉल कर सकते हैं

यहाँ उदाहरण है

class Foo {

    public function fun1() {
        echo 'non-static';   
    }

    public static function fun2() {
        echo (new self)->fun1();
    }
}

आप ऐसा कर सकते हैं, हालांकि यदि fun1इसका उपयोग नहीं किया जा रहा है self, तो इसे एक उदाहरण विधि बनाना तर्कसंगत नहीं है। Php में ऐसा करने का उचित तरीका घोषित करना है public static function fun1, फिर कक्षा को निर्दिष्ट करके कॉल करें Foo::fun1:। मुझे यकीन है कि उस सख्त मानक त्रुटि को ठीक करने का इरादा तरीका है।
टूलमेकरसेव
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.