PHP में :: (डबल कोलन) और -> (एरो) के बीच क्या अंतर है?


197

PHP में तरीकों तक पहुंचने के दो अलग-अलग तरीके हैं, लेकिन क्या अंतर है?

$response->setParameter('foo', 'bar');

तथा

sfConfig::set('foo', 'bar');

मैं मान रहा हूं ->(साइन या शेवरॉन से अधिक के साथ डैश) का उपयोग चर के कार्यों के लिए किया जाता है, और ::वर्गों के लिए कार्यों के लिए (डबल कॉलन) का उपयोग किया जाता है। सही बात?

है =>असाइनमेंट ऑपरेटर केवल एक सरणी के भीतर असाइन डेटा के लिए इस्तेमाल किया? क्या यह =असाइनमेंट ऑपरेटर के विपरीत है जिसका उपयोग किसी चर को त्वरित या संशोधित करने के लिए किया जाता है?



जवाबों:


173

जब बायां हिस्सा ऑब्जेक्ट इंस्टेंस होता है, तो आप उपयोग करते हैं ->। अन्यथा, आप उपयोग करते हैं ::

इसका मतलब है कि इसका ->उपयोग ज्यादातर उदाहरण के सदस्यों तक पहुंचने के लिए किया जाता है (हालांकि इसका उपयोग स्थैतिक सदस्यों तक पहुंचने के लिए भी किया जा सकता है, इस तरह के उपयोग को हतोत्साहित किया जाता है), जबकि ::आमतौर पर स्थैतिक सदस्यों तक पहुंचने के लिए उपयोग किया जाता है (हालांकि कुछ विशेष मामलों में, इसका उपयोग उदाहरण के सदस्यों तक पहुंचने के लिए किया जाता है। )।

सामान्य तौर पर, ::के लिए प्रयोग किया जाता है गुंजाइश संकल्प , और यह हो सकता है या तो एक वर्ग के नाम, parent, self, या (पीएचपी 5.3 में) staticअपनी बाईं ओर। parentउस वर्ग के सुपरक्लास के दायरे को संदर्भित करता है जहां इसका उपयोग किया जाता है; selfउस वर्ग के दायरे को संदर्भित करता है जहां इसका उपयोग किया जाता है; static"स्कोप" कहलाता है ( देर से स्थैतिक बाइंडिंग देखें )।

नियम यह है कि एक कॉल के साथ ::एक उदाहरण कॉल है अगर और केवल अगर:

  • लक्ष्य विधि को स्थिर घोषित नहीं किया गया है और
  • कॉल के समय संगत ऑब्जेक्ट संदर्भ होता है, जिसका अर्थ है कि ये सही होना चाहिए:
    1. कॉल एक ऐसे संदर्भ से किया जाता है जहां $thisमौजूद है और
    2. की कक्षा $thisया तो कहे जाने वाली विधि का वर्ग है या इसका उपवर्ग है।

उदाहरण:

class A {
    public function func_instance() {
        echo "in ", __METHOD__, "\n";
    }
    public function callDynamic() {
        echo "in ", __METHOD__, "\n";
        B::dyn();
    }

}

class B extends A {
    public static $prop_static = 'B::$prop_static value';
    public $prop_instance = 'B::$prop_instance value';

    public function func_instance() {
        echo "in ", __METHOD__, "\n";
        /* this is one exception where :: is required to access an
         * instance member.
         * The super implementation of func_instance is being
         * accessed here */
        parent::func_instance();
        A::func_instance(); //same as the statement above
    }

    public static function func_static() {
        echo "in ", __METHOD__, "\n";
    }

    public function __call($name, $arguments) {
        echo "in dynamic $name (__call)", "\n";
    }

    public static function __callStatic($name, $arguments) {
        echo "in dynamic $name (__callStatic)", "\n";
    }

}

echo 'B::$prop_static: ', B::$prop_static, "\n";
echo 'B::func_static(): ', B::func_static(), "\n";
$a = new A;
$b = new B;
echo '$b->prop_instance: ', $b->prop_instance, "\n";
//not recommended (static method called as instance method):
echo '$b->func_static(): ', $b->func_static(), "\n";

echo '$b->func_instance():', "\n", $b->func_instance(), "\n";

/* This is more tricky
 * in the first case, a static call is made because $this is an
 * instance of A, so B::dyn() is a method of an incompatible class
 */
echo '$a->dyn():', "\n", $a->callDynamic(), "\n";
/* in this case, an instance call is made because $this is an
 * instance of B (despite the fact we are in a method of A), so
 * B::dyn() is a method of a compatible class (namely, it's the
 * same class as the object's)
 */
echo '$b->dyn():', "\n", $b->callDynamic(), "\n";

आउटपुट:

B :: $ prop_static: B :: $ prop_static मान
B :: func_static (): B :: func_static में

$ b-> prop_instance: B :: $ prop_instance मूल्य
$ b-> func_static (): B :: func_static में

$ बी> func_instance ():
बी में :: func_instance
ए में :: func_instance
ए में :: func_instance

$ A-> dyn ():
A :: callDynamic में
गतिशील वंश में (__callStatic)

$ बी> dyn ():
A :: callDynamic में
गतिशील वंश में (__call)

3
" ->ज्यादातर उदाहरण सदस्यों तक पहुंचने के लिए उपयोग किया जाता है (हालांकि इसका उपयोग स्थैतिक सदस्यों तक पहुंचने के लिए भी किया जा सकता है, इस तरह के उपयोग को हतोत्साहित किया जाता है)" मुझे पता नहीं था कि यह हो सकता है। तो अगर यह स्थिर सदस्यों तक पहुँचने के लिए उपयोग किए जाने पर किसी तरह से "कार्य" करता है - तो व्यवहार में क्या अंतर होगा अगर कोई इसे इस तरह गलत तरीके से उपयोग करता है? जिज्ञासा के कारण।
23

4
@lucideer स्थैतिक विधियों के मामले में, यह अच्छे अभ्यास का प्रश्न है (विधि स्वयं वर्ग से संबंधित है), लेकिन PHP स्थैतिक विधि से कॉल करने पर शिकायत नहीं करता है ->। बेशक, आपको क्लास को सिर्फ एक स्टैटिक विधि से कॉल करने की आवश्यकता हो सकती है, इसलिए एक प्रदर्शन हिट भी है। संपत्तियों के साथ, हालांकि, अधिक मुद्दे हैं। एक STRICT चेतावनी को उठाया जाता है और यह काम कर भी सकती है और नहीं भी । ध्यान दें कि रिवर्स भी सच है - आप एक इंस्टेंस विधि को सांख्यिकीय रूप से कॉल कर सकते हैं, लेकिन यह और भी बदतर है (और आप $thisइस तरह के कार्यान्वयन में उपयोग नहीं कर सकते हैं )।
अर्टफेक्टो

52

::स्थिर संदर्भ में प्रयोग किया जाता है , अर्थात। जब किसी विधि या संपत्ति को स्थैतिक घोषित किया जाता है:

class Math {
    public static function sin($angle) {
        return ...;
    }
}

$result = Math::sin(123);

इसके अलावा, ::ऑपरेटर (स्कोप रिज़ॉल्यूशन ऑपरेटर, उर्फ पमायम नेकुडोटायम ) का उपयोग गतिशील संदर्भ में किया जाता है, जब आप किसी मूल वर्ग की विधि / संपत्ति का आह्वान करते हैं:

class Rectangle {
     protected $x, $y;

     public function __construct($x, $y) {
         $this->x = $x;
         $this->y = $y;
     }
}

class Square extends Rectangle {
    public function __construct($x) {
        parent::__construct($x, $x);
    }
}

->गतिशील संदर्भ में प्रयोग किया जाता है , अर्थात। जब आप कुछ वर्ग के कुछ उदाहरणों से निपटते हैं:

class Hello {
    public function say() {
       echo 'hello!';
    }
}

$h = new Hello();
$h->say();

वैसे: मुझे नहीं लगता कि सिम्फनी का उपयोग करना एक अच्छा विचार है जब आपके पास कोई ओओपी अनुभव नहीं है।


24

वास्तव में इस प्रतीक से हम एक वर्ग विधि कह सकते हैं जो स्थिर है और अन्य आरंभीकरण पर निर्भर नहीं है ...

class Test {

    public $name;

    public function __construct() {
        $this->name = 'Mrinmoy Ghoshal';
    }

    public static function doWrite($name) {
        print 'Hello '.$name;
    }

    public function write() {
        print $this->name;
    }
}

यहां doWrite()फ़ंक्शन किसी अन्य विधि या चर पर निर्भर नहीं है, और यह एक स्थिर विधि है। इसलिए हम इस ऑपरेटर को इस वर्ग की वस्तु को शुरू किए बिना इस विधि से बुला सकते हैं।

Test::doWrite('Mrinmoy'); // Output: Hello Mrinmoy.

लेकिन अगर आप writeइस तरीके से कॉल करना चाहते हैं , तो यह एक त्रुटि उत्पन्न करेगा क्योंकि यह आरंभीकरण पर निर्भर है।


16

=>ऑपरेटर एक साहचर्य सरणी में असाइन कुंजी-मान जोड़ों के लिए प्रयोग किया जाता है। उदाहरण के लिए:

$fruits = array(
  'Apple'  => 'Red',
  'Banana' => 'Yellow'
);

यह अर्थ foreachकथन में समान है :

foreach ($fruits as $fruit => $color)
  echo "$fruit is $color in color.";

14

स्थैतिक और तात्कालिक तरीकों और गुणों के बीच का अंतर उन लोगों के लिए सबसे बड़ी बाधाओं में से एक लगता है जो अभी PHP 5 में OOP PHP के साथ शुरू करते हैं।

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

तीर ऑपरेटर, इसके विपरीत, उन तरीकों या गुणों को कॉल करता है जो ऑब्जेक्ट की एक आवृत्ति के संदर्भ से हैं।

स्टैटिक विधियाँ ऑब्जेक्ट मॉडल में विशेष रूप से उपयोगी हो सकती हैं जो विधियों को बनाने और हटाने के लिए डेटाबेस से जुड़ी होती हैं, क्योंकि आप सम्मिलित टेबल आईडी पर रिटर्न वैल्यू सेट कर सकते हैं और फिर पंक्ति आईडी द्वारा ऑब्जेक्ट को इंस्टेंट करने के लिए कंस्ट्रक्टर का उपयोग कर सकते हैं।


2

हां, मैंने अभी अपनी पहली फिल्म हिट की है 'PHP Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM'। मेरा बुरा, मेरे पास एक $instance::method()होना चाहिए था $instance->method()। मुझे मूर्ख।

विचित्र बात यह है कि यह अभी भी मेरी स्थानीय मशीन पर ठीक काम करता है (PHP 5.3.8 चल रहा है) - कुछ भी नहीं, error_reporting = E_ALL के साथ एक चेतावनी भी नहीं - लेकिन परीक्षण सर्वर पर बिल्कुल नहीं, वहाँ यह सिर्फ एक सिंटैक्स त्रुटि के साथ विस्फोट होता है और ब्राउज़र में एक सफेद स्क्रीन। चूंकि PHP लॉगिंग को परीक्षण मशीन में बंद कर दिया गया था, और होस्टिंग कंपनी इसे चालू करने के लिए बहुत व्यस्त थी, इसलिए यह बहुत स्पष्ट नहीं था।

तो, चेतावनी का शब्द: जाहिर है, कुछ PHP इंस्टॉलेशन आपको $ इंस्टेंस :: विधि () का उपयोग करने देंगे, जबकि अन्य नहीं।

यदि कोई इस पर विस्तार कर सकता है कि वह क्यों है, कृपया करें।

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