नया स्व बनाम नया स्थैतिक


513

मैं PHP 5.2 पर काम करने के लिए PHP 5.3 लाइब्रेरी को परिवर्तित कर रहा हूं। मेरे रास्ते में मुख्य बात यह है कि देर से स्थैतिक बंधन का उपयोग होता है return new static($options);, अगर मैं return new self($options)इसे उसी परिणाम में बदल दूंगा?

बीच क्या अंतर है new selfऔर new static?

जवाबों:


888

क्या मुझे वही परिणाम मिलेंगे?

ज़रुरी नहीं। मुझे PHP 5.2 के लिए वर्कअराउंड का पता नहीं है, हालाँकि।

बीच क्या अंतर है new selfऔर new static?

selfउसी वर्ग को संदर्भित करता है जिसमें newकीवर्ड वास्तव में लिखा गया है।

staticPHP 5.3 के देर से स्थैतिक बाइंडिंग में, पदानुक्रम में जो भी वर्ग आप पर विधि कहा जाता है को संदर्भित करता है।

निम्नलिखित उदाहरण में, Bदोनों विधियों से विरासत में मिला है Aselfमंगलाचरण के लिए बाध्य है A, क्योंकि यह में परिभाषित किया गया है Aपहली विधि के के कार्यान्वयन, जबकि staticकहा जाता वर्ग के लिए बाध्य है (यह भी देखें get_called_class())।

class A {
    public static function get_self() {
        return new self();
    }

    public static function get_static() {
        return new static();
    }
}

class B extends A {}

echo get_class(B::get_self());  // A
echo get_class(B::get_static()); // B
echo get_class(A::get_self()); // A
echo get_class(A::get_static()); // A

समझ में आता है। मुझे लगता है कि सबसे अच्छा दांव क्लास नाम को उस फ़ंक्शन को पास करना है जो देर से स्थैतिक बंधन का उपयोग कर रहा है और फिर नए $ className ($ विकल्प) लौटाता है;
माइक

12
आपको कक्षा के नाम को "पास" नहीं करना है, आप हमेशा कर सकते हैं get_called_class(), जो प्रभावी रूप से समान है __CLASS__, लेकिन एलएसबी संगत है।
छायाखंड

7
get_called_class <PHP5.3 में मौजूद नहीं है। इसलिए यदि आप PHP5.2 में तात्कालिक वस्तु का वर्ग नाम प्राप्त करना चाहते हैं, तो यह फ़ंक्शन मदद नहीं करता है जब लाइब्रेरी को PHP 5.3 से PHP 5.2 में बदलने की कोशिश की जा रही है
txwikinger

2
फ़ंक्शन को स्वयं के रूप में कहा जाता है :: एफ़ंक्शन () ऐसा व्यवहार करता है "मैं उस वर्ग के संदर्भ में निष्पादित करूंगा, जिसे मैं शारीरिक रूप से संबंधित हूं।" और फ़ंक्शन को स्थिर के रूप में कहा जाता है :: TheFunction () "मैं उस वर्ग के संदर्भ में निष्पादित करूंगा जो वास्तव में बाहरी दुनिया द्वारा बुलाया गया है" जैसा व्यवहार करता है। (उत्तराधिकार परिदृश्य मानते हुए)। धन्यवाद
शुभ्रांशु

2
मेरे सिर में, मैं बस जो कुछ भी सहज है, उसे लेता हूं और उसे विपरीत बनाता हूं। आप नामकरण के आधार पर सोचेंगे, selfखुद ही लौट आएंगे, और staticकुछ ऐसा लौटाएंगे जिसे ओवरराइड नहीं किया जा सकता ... लेकिन लो और निहारना इसके विपरीत है। मैं PHP के नामकरण, सम्मेलनों और समग्र शैली से प्रभावित होना कभी नहीं चाहता। -_-
एहनबाकद

23

यदि इस कोड की विधि स्थिर नहीं है, तो आप 5.2 का उपयोग करके काम के आसपास प्राप्त कर सकते हैं get_class($this)

class A {
    public function create1() {
        $class = get_class($this);
        return new $class();
    }
    public function create2() {
        return new static();
    }
}

class B extends A {

}

$b = new B();
var_dump(get_class($b->create1()), get_class($b->create2()));

परिणाम:

string(1) "B"
string(1) "B"

17
यदि विधि स्थिर नहीं है, तो देर से स्थिर बाइंडिंग पूरी तरह अप्रासंगिक हो जाती है।
BoltClock

1
उदाहरण के लिए, आप इसे "कॉपी" विधि में उपयोग कर सकते हैं, जहां ऑब्जेक्ट का उपयोग किए बिना कॉपी किया जाता है clone, लेकिन बस गुणों को फिर से बनाने और सेट करने से। $copy = new static(); $copy->set($this->get()); return $copy;
Marius Balčytis

9
@BoltClock निश्चित रूप से नहीं? यदि आप किसी उपवर्ग की आवृत्ति विधि के भीतर एक ओवरराइड स्टैटिक विधि कह रहे हैं, तो बेस क्लास या उप-वर्ग के उस स्टैटिक विधि का उपयोग किया जाता है self::या नहीं, आपकी पसंद static::प्रभावित करने वाली है। किसी कारण के अभाव में ऐसा है कि एक स्थिति स्वाभाविक रूप से होने वाली बुरा व्यवहार को इंगित करता है सोचने के लिए (और मैं किसी भी कारण नहीं दिख रहा है यह क्यों इतना होना चाहिए), के बीच विकल्प self::और static::गैर स्थिर तरीकों के भीतर बस के रूप में प्रासंगिक के रूप में यह में है स्थैतिक तरीके। क्या मैंने आपकी टिप्पणी को गलत समझा है, या हममें से कोई एक गलत है?
मार्क अमेरी

4
@ मर्क अमेरी: हम्म मैंने ऐसा नहीं सोचा था। आप बिल्कुल सही कह रहे है। मैंने यह मान लिया था कि किसी भी स्थिर तरीके को प्रश्न पद्धति में नहीं कहा जा सकता है, लेकिन आपके उदाहरण के आधार पर, मैं देख सकता हूं कि यह बहुत ही भोली धारणा होगी।
BoltClock

स्वर्गीय स्टेटिक बाइंडिंग doc => php.net/manual/en/language.oop5.late-static-bindings.php
DevWL

7

दूसरों के जवाब के अलावा:

स्टेटिक :: रनटाइम जानकारी का उपयोग करके गणना की जाएगी।

इसका मतलब है कि आप static::एक वर्ग संपत्ति में उपयोग नहीं कर सकते क्योंकि गुण मान:

संकलन समय पर मूल्यांकन करने में सक्षम होना चाहिए और रन-टाइम जानकारी पर निर्भर नहीं होना चाहिए।

class Foo {
    public $name = static::class;

}

$Foo = new Foo;
echo $Foo->name; // Fatal error

का उपयोग करते हुए self::

class Foo {
    public $name = self::class;

}
$Foo = new Foo;
echo $Foo->name; // Foo

कृपया ध्यान दें कि मेरे द्वारा बनाए गए कोड में घातक त्रुटि टिप्पणी यह ​​नहीं दर्शाती है कि त्रुटि कहां हुई है, त्रुटि पहले हुई थी क्योंकि वस्तु को तुरंत हटा दिया गया था क्योंकि @Grapestain टिप्पणियों में उल्लिखित है


4
ध्यान दें कि त्रुटि लाइन 2 पर डाली गई है public $name = static::class;, रेखा 7 पर नहीं, जैसा कि उदाहरण द्वारा सुझाया गया है। त्रुटि कहती है: "स्थिर :: वर्ग का उपयोग संकलन-समय वर्ग के नाम समाधान के लिए नहीं किया जा सकता है" जो इंगित करता है कि समस्या वह नहीं है जहां आप $ नाम फ़ील्ड तक पहुंचने का प्रयास करते हैं, लेकिन इससे पहले, PHP वर्ग के संकलन पर। लाइन 7 (या 6) पहले उदाहरण में नहीं पहुंचेगी।
sbnc.eu

@Grapestain मैंने उदाहरण में जो टिप्पणी की वह अंतिम परिणाम दिखाने के लिए थी और यह इंगित करने के लिए नहीं कि त्रुटि वास्तव में कहां हुई थी। लेकिन वैसे भी उस ओर इशारा करने के लिए धन्यवाद।
बारिश

ठीक है, मुझे आलोचना करने का मतलब नहीं था, बस स्पष्ट किया कि मुझे इस उम्मीद में सबसे पहले उलझन में क्या यह दूसरों की मदद कर सकता है। वैसे भी सहायक उदाहरण!
sbnc.eu
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.