नया स्वयं क्या करता है (); PHP में मतलब है?


110

मैंने कभी इस तरह कोड नहीं देखा है:

public static function getInstance()
{
    if ( ! isset(self::$_instance)) {
        self::$_instance = new self();
    }
    return self::$_instance;
}

क्या यह वैसा ही है new className()?

संपादित करें

यदि वर्ग विरासत में है, तो यह किस वर्ग को इंगित करता है?



@ स्टीरियोफॉग, क्या आपका मतलब है कि सिंगलटन पैटर्न को छोड़ दिया जाना चाहिए? लेकिन सभी चीजें एक कारण के लिए मौजूद हैं, है ना?
user198729

ओह, मैं इस बात से सहमत हूँ: सिंगलटन को कारखाने द्वारा प्रतिस्थापित किया जाना चाहिए
user198729

@stereofrog सिंगलटन यूनिट-टेस्टिंग के लिए ज़हर हैं, यह बेहद मुश्किल है कि किसी ऐसी चीज़ पर अपरिवर्तनीय परीक्षण किया जाए जो एक कॉल से दूसरे कॉल पर स्टेट बदलती है।
डेविड

दुर्भाग्य से, यह विधि विस्तारित नहीं होगी। यह हमेशा आपको उस कक्षा से एक नई वस्तु देगा जिसमें यह फ़ंक्शन परिभाषित किया गया था।
एरेस

जवाबों:


211

self उस कक्षा को इंगित करता है जिसमें यह लिखा गया है।

इसलिए, यदि आपकी getInstance विधि एक वर्ग नाम में है MyClass, तो निम्न पंक्ति:

self::$_instance = new self();

के रूप में ही करेंगे:

self::$_instance = new MyClass();



संपादित करें: टिप्पणियों के बाद एक और अधिक informations।

यदि आपके पास दो कक्षाएं हैं जो एक-दूसरे का विस्तार करती हैं, तो आपके पास दो स्थितियां हैं:

  • getInstance बाल वर्ग में परिभाषित किया गया है
  • getInstance मूल वर्ग में परिभाषित किया गया है

पहली स्थिति इस तरह दिखेगी (मैंने सभी गैर-आवश्यक कोड हटा दिए हैं, इस उदाहरण के लिए - आपको सिंगलटन व्यवहार प्राप्त करने के लिए इसे वापस जोड़ना होगा) *:

class MyParentClass {

}
class MyChildClass extends MyParentClass {
    public static function getInstance() {
        return new self();
    }
}

$a = MyChildClass::getInstance();
var_dump($a);

यहाँ, आपको मिलेगा:

object(MyChildClass)#1 (0) { } 

जिसका अर्थ selfहै MyChildClass- अर्थात वह वर्ग जिसमें यह लिखा गया है।


दूसरी स्थिति के लिए, कोड इस तरह दिखेगा:

class MyParentClass {
    public static function getInstance() {
        return new self();
    }
}
class MyChildClass extends MyParentClass {

}

$a = MyChildClass::getInstance();
var_dump($a);

और आपको इस तरह का आउटपुट मिलेगा:

object(MyParentClass)#1 (0) { }

जिसका अर्थ selfहै MyParentClass- अर्थात यहाँ भी, वह वर्ग जिसमें यह लिखा गया है




PHP <5.3 के साथ, यह "वह वर्ग जिसमें यह लिखा गया है" महत्वपूर्ण है - और कभी-कभी समस्याएं पैदा कर सकता है।

यही कारण है कि PHP 5.3 staticकीवर्ड के लिए एक नया उपयोग प्रस्तुत करता है: अब इसका उपयोग ठीक उसी जगह किया जा सकता है जहां हमने selfउन उदाहरणों में उपयोग किया था:

class MyParentClass {
    public static function getInstance() {
        return new static();
    }
}
class MyChildClass extends MyParentClass {

}

$a = MyChildClass::getInstance();
var_dump($a);

लेकिन, staticइसके बजाय self, अब आपको मिलेगा:

object(MyChildClass)#1 (0) { } 

जिसका अर्थ है कि जिस वर्ग का उपयोग किया जाता है (हम उपयोग किया जाता है ), और न कि जिस पर यह लिखा गया है, उस staticतरह के अंक ।MyChildClass::getInstance()

बेशक, selfमौजूदा एप्लिकेशन को नहीं तोड़ने के लिए व्यवहार को बदल दिया गया है - PHP 5.3 ने केवल एक नया व्यवहार जोड़ा, staticकीवर्ड को पुनर्चक्रित किया ।


और, PHP 5.3 के बारे में बोलते हुए, आप PHP मैनुअल के लेट स्टेटिक बाइंडिंग पृष्ठ पर एक नज़र डालना चाहते हैं ।


@Paul: heu ... का अर्थ है "स्व एक उपनाम के रूप में कार्य करता है", या "स्वयं के लिए अंक का प्रकार" - "डिजाइनर" क्रिया, फ्रेंच में, इसके लिए इस्तेमाल किया जा सकता है - मुझे लगता है कि स्थितियों में से एक है जिसमें अंग्रेजी में एक ही शब्द का उपयोग करना एक अच्छा विचार नहीं है;
पास्कल मार्टिन

क्या होगा अगर वहाँ है baseclass, classजो यह इंगित करता है?
user198729

@user: मैंने अपने उत्तर को कुछ और अधिक जानकारी देने के लिए संपादित किया है selfऔर विरासत के बारे में ; और मैंने staticPHP 5.3 के बारे में कुछ जानकारी भी शामिल की है ;; उम्मीद है कि यह मदद करता है :-)
पास्कल मार्टिन

10

यह सिंगलटन पैटर्न का कार्यान्वयन प्रतीत होता है । फ़ंक्शन को स्टेटिक रूप से कहा जाता है और जांचता है कि क्या स्थिर वर्ग के पास चर $_instanceसेट है।

यदि ऐसा नहीं है, तो यह स्वयं की एक आवृत्ति को आरंभ करता है ( new self()) और इसे इसमें संग्रहीत करता है $_instance

यदि आप कॉल className::getInstance()करते हैं तो आपको हर कॉल पर एक और एक ही क्लास का उदाहरण मिलेगा , जो सिंगलटन पैटर्न का बिंदु है।

मैंने कभी नहीं देखा कि यह इस तरह से किया गया है, हालांकि, और ईमानदारी से नहीं पता था कि यह संभव था। $_instanceकक्षा में क्या घोषित किया गया है?


1
$_instanceघोषित किया गया हैpublic static $_instance;
आतिफ

7

यह सबसे अधिक संभावना सिंगलटन डिजाइन पैटर्न में उपयोग किया जाता है, जिसमें कंस्ट्रक्टर को निजी के रूप में परिभाषित किया जाता है ताकि त्वरित होने से बचने के लिए, डबल कोलन (::)ऑपरेटर उन सदस्यों तक पहुंच सके, जिन्हें कक्षा के अंदर स्थिर घोषित किया गया है, इसलिए यदि स्थिर सदस्य हैं, तो छद्म चर $ इसका उपयोग नहीं किया जा सकता है, इसलिए कोड का उपयोग स्वयं के बजाय किया जाता है, सिंग्लेटन्स अच्छी प्रोग्रामिंग प्रथाएं हैं जो केवल डेटाबेस कनेक्टर योजक जैसे ऑब्जेक्ट के 1 उदाहरण की अनुमति देगा। क्लाइंट कोड से, उस एक्सेस को एक्सेस करना एक सिंगल एक्सेस पॉइंट बनाकर किया जाएगा, इस मामले में उन्होंने इसे नाम दिया getInstance(), getInstance अपने आप में एक ऐसा फंक्शन था जिसने ऑब्जेक्ट को मूल रूप से नए कीवर्ड का उपयोग करके ऑब्जेक्ट का निर्माण किया जिसका अर्थ कंस्ट्रक्टर मेथड था। यह भी कहा जाता है।

if(!isset(self::instance))यदि कोई ऑब्जेक्ट पहले से ही बनाया गया है, तो लाइन चेक करता है, आप यह समझ नहीं पाए कि यह कोड है क्योंकि कोड सिर्फ एक टुकड़ा है, कहीं शीर्ष में, शायद जैसे स्थैतिक सदस्य होने चाहिए

private static $_instance = NULL; 

सामान्य कक्षाओं में हम इस सदस्य तक बस पहुँच सकते थे

$this->_instance = 'something';

लेकिन इसकी घोषित स्थैतिक और इसलिए हम इसके बजाय $ का उपयोग नहीं कर सकते

self::$_instance

जाँच करके कि क्या इस स्थिर वर्ग चर पर संग्रहीत कोई वस्तु है, वर्ग तब एकल उदाहरण बनाने या नहीं बनाने का निर्णय ले सकता है, इसलिए यदि इसका सेट नहीं है, तो!, इसका अर्थ है कि स्थैतिक सदस्य $ _instance पर कोई वस्तु मौजूद नहीं है, फिर! यह एक नई वस्तु उत्पन्न करता है, इसे स्थिर सदस्य $_instanceमें कमांड द्वारा संग्रहीत किया जाता है

self::$_instance = new self();

और इसे ग्राहक कोड को लौटा दिया। ग्राहक कोड तब अपने सार्वजनिक तरीकों के साथ ऑब्जेक्ट के एकल उदाहरण का खुशी से उपयोग कर सकता है, लेकिन क्लाइंट कोड में, सिंगल एक्सेस पॉइंट को कॉल करना, अर्थात getInstance()विधि भी मुश्किल है, इसे इस तरह से कॉल करना होगा

$thisObject = className::getInstance();

कारण, अपने आप में कार्य को स्थिर घोषित किया जाता है।


2

हां, यह ऐसा है new className()(उस पद्धति से युक्त वर्ग का जिक्र), शायद सिंगलटन पैटर्न में उपयोग किया जाता है जहां कंस्ट्रक्टर निजी है।


कोई व्यक्ति PHP में सिंगलटन पैटर्न का उपयोग क्यों करेगा? जब तक एक डेमन जैसे कार्यक्रम में उपयोग नहीं किया जाता है, सिंगलटन केवल जीवित रहेगा जबकि स्क्रिप्ट चलती है और फिर कार्यक्रम के साथ गायब हो जाती है।
ILikeTacos

4
एक वैश्विक चर का उपयोग करने के लिए वैश्विक रूप से परेशान घोषित करने से बचने के लिए
सैम एडम्श

0

यदि कक्षा विरासत में मिली है, तो बच्चे से getInstance () कॉलिंग आपको बच्चे का उदाहरण नहीं देगी। यह केवल माता-पिता के उदाहरण का एक उदाहरण देता है। ऐसा इसलिए है क्योंकि हम नए स्व को कहते हैं ()।

यदि आप चाहते हैं कि चाइल्ड क्लास चाइल्ड क्लास का एक उदाहरण लौटाएगा, तो गेटइनस्टांस () में नए स्टेटिक () का उपयोग करें और फिर वह चाइल्ड क्लास इंस्टेंस को लौटा देगा। इसे लेट बाइंडिंग कहा जाता है !!

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.