क्या PHP में स्थिर कक्षाएं बनाना संभव है (जैसे C #)?


139

मैं PHP में एक स्थिर वर्ग बनाना चाहता हूं और यह ऐसा व्यवहार करता है जैसे यह C # में करता है, इसलिए

  1. कक्षा में पहली कॉल पर कंस्ट्रक्टर को स्वचालित रूप से कॉल किया जाता है
  2. कोई तात्कालिकता की आवश्यकता नहीं है

कुछ इस तरह ...

static class Hello {
    private static $greeting = 'Hello';

    private __construct() {
        $greeting .= ' There!';
    }

    public static greet(){
        echo $greeting;
    }
}

Hello::greet(); // Hello There!

क्या आप संक्षेप में बता सकते हैं कि एक स्थिर वर्ग को कैसा व्यवहार करना चाहिए? क्या यह एक उपयोगिता का कार्यान्वयन है?
xtofl

बस अपनी खुद की राय को बाहर फेंक रहा हूं, लेकिन पीएचपी में मेरे अनुभव से, पवित्रता, परीक्षणशीलता और स्केलेबिलिटी के लिए, स्थैतिक कक्षाएं बहुत अधिक पूरी तरह से स्टेटलेस होनी चाहिए, एक वस्तु उन्मुख एक की तुलना में अधिक कार्यात्मक प्रोग्रामिंग जैसी एपीआई पेश करें, और आम तौर पर। पूरी तरह से तात्कालिक वस्तुओं या सहायकों या इसी तरह के निर्माणों के लिए उपयोगिता रैपर के लिए पहुंच योग्य पहलुओं के रूप में सबसे अच्छा उपयोग किया जाता है अगर वे भी बिल्कुल भी उपयोग किए जाते हैं।
mopsyd

जवाबों:


200

PHP में आपके पास स्थैतिक कक्षाएं हो सकती हैं, लेकिन वे निर्माता को स्वचालित रूप से कॉल नहीं करते हैं (यदि आप कोशिश करते हैं और कॉल करते हैं self::__construct()तो आपको एक त्रुटि मिलेगी)।

इसलिए आपको एक initialize()फ़ंक्शन बनाना होगा और इसे प्रत्येक विधि में कॉल करना होगा:

<?php

class Hello
{
    private static $greeting = 'Hello';
    private static $initialized = false;

    private static function initialize()
    {
        if (self::$initialized)
            return;

        self::$greeting .= ' There!';
        self::$initialized = true;
    }

    public static function greet()
    {
        self::initialize();
        echo self::$greeting;
    }
}

Hello::greet(); // Hello There!


?>

20
मैं अक्सर ऐसा सिर्फ एक ही जगह पर सभी कार्यों को लपेटने के लिए करता हूं। IE उपयोगिता :: doSomethingUseful ();
स्मैक .००० sm

16
इसके बजाय एक सार्वजनिक समारोह करना और वर्ग की घोषणा के ठीक बाद इसे कॉल Therefore you'd have to create an initialize() function and call it in each method:करना आसान होगा initialize
chacham15

4
मुझे पता है कि यह बहुत पुराना है, लेकिन अब आप जादू का उपयोग कर सकते हैं __callStatic इसलिए जब आप किसी भी स्थिर विधि या किसी भी चीज़ को कॉल करते हैं __callStatic, तो यह पहले कॉल करेगा , वहां आप देख सकते हैं कि क्या इसे आरंभीकृत किया गया था और फिर self::$methodआप जो भी कॉल कर रहे हैं। यदि यह अभी भी सीधे तरीके से कॉल कर रहा है, तो सब कुछ निजी में बदलने का प्रयास करें और वहां देखें।
मतिलासौरिति

1
यदि दो धागे एक ही समय में अभिवादन करते हैं तो क्या होता है? जैसा कि कोई सिंक्रोनाइज़ेशन नहीं है, आरंभ में दो बार कॉल नहीं किया जाएगा (जो इस मामले में ठीक है, लेकिन कई अन्य मामलों में नहीं होगा)। या php सिंगल थ्रेडेड और नॉन-प्रिपेक्टिव जैसे नोड है?
जॉन लिटिल

53

ग्रेग के जवाब के अलावा, मैं कंस्ट्रक्टर को निजी सेट करने की सिफारिश करूंगा ताकि क्लास को तुरंत करना असंभव हो।

तो मेरी विनम्र राय में यह ग्रेग के आधार पर एक अधिक पूर्ण उदाहरण है:

<?php

class Hello
{
    /**
     * Construct won't be called inside this class and is uncallable from
     * the outside. This prevents instantiating this class.
     * This is by purpose, because we want a static class.
     */
    private function __construct() {}
    private static $greeting = 'Hello';
    private static $initialized = false;

    private static function initialize()
    {
        if (self::$initialized)
            return;

        self::$greeting .= ' There!';
        self::$initialized = true;
    }

    public static function greet()
    {
        self::initialize();
        echo self::$greeting;
    }
}

Hello::greet(); // Hello There!


?>

1
यह एक महान दृष्टिकोण है, निर्माण कार्य को लागू नहीं किया जा सकता है, यदि आपका सिंगेलटन कुछ ऐसी वस्तुओं से विरासत में मिला है, जिन्हें सार्वजनिक निर्माणकर्ता की आवश्यकता है।
एरिक हर्लिट्ज़

4
@EricHerlitz यह प्रश्न एकल के बारे में नहीं है, यह स्थैतिक कक्षाओं के बारे में है। आप एक स्थिर वर्ग बनाना चाहते हैं जो उस वर्ग से विरासत में मिला है जिसका तात्पर्य तात्कालिक होना है?
मार्क अमेरी

3
समान रूप से कक्षा को समान रूप से घोषित करने के साथ इसे तत्काल होने से रोकते हैं और स्थिर तरीकों से कॉल करने की अनुमति देते हैं।
bstoney

24

आपके पास "स्थिर" जैसी कक्षाएं हो सकती हैं। लेकिन मुझे लगता है, कि वास्तव में महत्वपूर्ण कुछ याद आ रही है: php में आपके पास एक ऐप-चक्र नहीं है, इसलिए आपको अपने पूरे आवेदन में एक वास्तविक स्थैतिक (या सिंगलटन) नहीं मिलेगा ...

PHP में सिंगलटन देखें


1
स्टैटिक क्लासेस और सिंगलनेट्स सिर्फ 2 अलग-अलग चीजें हैं।
मैक्स कट्सिन्स

4
final Class B{

    static $staticVar;
    static function getA(){
        self::$staticVar = New A;
    }
}

बी का स्टेकचर एक सिंगलटन हैंडलर है जिसे आप ए में भी कर सकते हैं

Class a{
    static $instance;
    static function getA(...){
        if(!isset(self::$staticVar)){
            self::$staticVar = New A(...);
        }
        return self::$staticVar;
    }
}

यह सिंगलटन उपयोग है $a = a::getA(...);


3

मैं आम तौर पर नियमित रूप से गैर स्थिर कक्षाओं को लिखना पसंद करता हूं और ऑब्जेक्ट के एकल (सुडोकू स्थिर) उदाहरणों को इंस्टेंट करने के लिए फ़ैक्टरी क्लास का उपयोग करता हूं।

इस तरह से निर्माणकर्ता और विध्वंसक सामान्य रूप से काम करते हैं, और अगर मैं चाहूँ तो मैं अतिरिक्त गैर स्थिर उदाहरण बना सकता हूँ (उदाहरण के लिए एक दूसरा DBX)

मैं हर समय इसका उपयोग करता हूं और विशेष रूप से कस्टम डीबी स्टोर सत्र संचालकों को बनाने के लिए उपयोगी है, क्योंकि जब पृष्ठ समाप्त हो जाता है तो विनाशकारी सत्र को डेटाबेस में धकेल देगा।

एक और लाभ यह है कि आप ऑर्डर को अनदेखा कर सकते हैं क्योंकि आप चीजों को कॉल करते हैं क्योंकि सब कुछ मांग पर सेटअप होगा।

class Factory {
    static function &getDB ($construct_params = null)
    {
        static $instance;
        if( ! is_object($instance) )
        {
            include_once("clsDB.php");
            $instance = new clsDB($construct_params);   // constructor will be called
        }
        return $instance;
    }
}

DB वर्ग ...

class clsDB {

    $regular_public_variables = "whatever";

    function __construct($construct_params) {...}
    function __destruct() {...}

    function getvar() { return $this->regular_public_variables; }
}

कहीं भी आप इसे केवल कॉल का उपयोग करना चाहते हैं ...

$static_instance = &Factory::getDB($somekickoff);

फिर सभी तरीकों को गैर स्थिर मानें (क्योंकि वे हैं)

echo $static_instance->getvar();

1
यह वास्तव में एक सिंगलटन पैटर्न कार्यान्वयन है, और इसका वास्तव में उपयोग नहीं किया जाना चाहिए - इसके बजाय निर्भरता इंजेक्शन से चिपके रहें, जो परीक्षण योग्य है और इसे डीबग करना आसान बनाता है।
थॉमस हेन्सन

1
क्या आप इस बात के लिए एक उदाहरण दे सकते हैं कि इस उत्तर के लिए निर्भरता इंजेक्शन का उपयोग कैसे किया जाता है और यह कैसे अधिक परीक्षण योग्य बनाता है?
cjsimon

2

ऑब्जेक्ट को स्थैतिक रूप से परिभाषित नहीं किया जा सकता है लेकिन यह काम करता है

final Class B{
  static $var;
  static function init(){
    self::$var = new A();
}
B::init();

1
एंड्रियास निडरमेयर: यानी कैसे php काम करता है (ऐप-साइकल = एक एकल अनुरोध) लेकिन एक सिंगलटन (एक जो अनुरोध में रहता है) php में एक सकारात्मकता है (php एक सिंगलटन एक ऑब्जेक्ट है जिसमें 1 उदाहरण है (ऐप के भीतर) चक्र)
borrel
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.