इस से अधिक $ का उपयोग कब करें?


1997

PHP 5 में, उपयोग करने selfऔर के बीच क्या अंतर है $this?

प्रत्येक उपयुक्त कब है?



मैं पूछने जा रहा हूँ कि क्या अंतर है: कॉन ए; $
यह-

जवाबों:


1727

संक्षिप्त जवाब

$thisवर्तमान वस्तु को संदर्भित करने के लिए उपयोग करें । selfवर्तमान वर्ग को संदर्भित करने के लिए उपयोग करें । दूसरे शब्दों में, $this->memberगैर-स्थैतिक सदस्यों के self::$memberलिए उपयोग करें , स्थिर सदस्यों के लिए उपयोग करें ।

पूरा जवाब

यहाँ का एक उदाहरण है सही के उपयोग $thisऔर selfगैर स्थिर और स्थिर सदस्य चर के लिए:

<?php
class X {
    private $non_static_member = 1;
    private static $static_member = 2;

    function __construct() {
        echo $this->non_static_member . ' '
           . self::$static_member;
    }
}

new X();
?>

यहाँ का एक उदाहरण है गलत के उपयोग $thisऔर selfगैर स्थिर और स्थिर सदस्य चर के लिए:

<?php
class X {
    private $non_static_member = 1;
    private static $static_member = 2;

    function __construct() {
        echo self::$non_static_member . ' '
           . $this->static_member;
    }
}

new X();
?>

यहाँ का एक उदाहरण है बहुरूपता के साथ $thisसदस्य कार्यों के लिए:

<?php
class X {
    function foo() {
        echo 'X::foo()';
    }

    function bar() {
        $this->foo();
    }
}

class Y extends X {
    function foo() {
        echo 'Y::foo()';
    }
}

$x = new Y();
$x->bar();
?>

यहाँ सदस्य कार्यों के लिए उपयोग करके बहुरूपी व्यवहार को दबाने का एक उदाहरण दिया गया selfहै:

<?php
class X {
    function foo() {
        echo 'X::foo()';
    }

    function bar() {
        self::foo();
    }
}

class Y extends X {
    function foo() {
        echo 'Y::foo()';
    }
}

$x = new Y();
$x->bar();
?>

विचार यह है कि जो भी वर्तमान वस्तु का सटीक प्रकार है, $this->foo()उसके foo()सदस्य फ़ंक्शन को कॉल करता है। यदि वस्तु का है type X, तो यह कॉल करता है X::foo()। यदि ऑब्जेक्ट का है type Y, तो यह कॉल करता है Y::foo()। लेकिन स्वयं के साथ :: फू (), X::foo()हमेशा कहा जाता है।

से http://www.phpbuilder.com/board/showthread.php?t=10354489 :

Http://board.phpbuilder.com/member.php?145249-laserlight द्वारा


330
यह उत्तर अत्यंत सरल है। जैसा कि अन्य उत्तरों में कहा गया है, वर्तमान वर्ग को संदर्भित करने के लिए selfगुंजाइश रिज़ॉल्यूशन ऑपरेटर के साथ प्रयोग किया जाता है ::; यह स्थैतिक और गैर-स्थैतिक दोनों संदर्भों में किया जा सकता है। इसके अतिरिक्त, $thisस्थैतिक तरीकों को कॉल करने के लिए उपयोग करना पूरी तरह से कानूनी है (लेकिन फ़ील्ड को संदर्भित करने के लिए नहीं)।
आर्टिफैक्टो

50
इसके अलावा स्थिर का उपयोग करने पर विचार करें: के बजाय :: आत्म यदि 5.3+ पर youre। यह आपके लिए सिरदर्द पैदा कर सकता है अन्यथा, मेरा उत्तर नीचे क्यों देखें।
सूक

25
-1। यह उत्तर भ्रामक है, अधिक जानकारी के लिए अन्य उत्तरों को पढ़ें।
पचेरियर

6
यह अत्यधिक सरलीकृत हो सकता है, लेकिन इसने मेरे मूल विस्फोट के बिना मेरे मूल स्तर के प्रश्न का उत्तर दिया। मुझे कुछ और जानकारी मिली, जो मुझे और भी मददगार लगीं, लेकिन अब मैं यह जानने की कोशिश कर रहा था कि मैंने अपनी क्लास की विशेषताओं को इस $ के साथ क्यों मारा-> अट्रिब और स्वयं के साथ वर्ग की निरंतरता :: स्थिरांक। इससे मुझे यह समझने में मदद मिली कि बेहतर
MydKnight

किस बारे में $this::?
जेम्स

742

कीवर्ड सेल्फ केवल 'वर्तमान वर्ग' को संदर्भित नहीं करता है , कम से कम उस तरीके से नहीं जो आपको स्थिर सदस्यों तक सीमित करता है। एक गैर-स्थैतिक सदस्य के संदर्भ में, वर्तमान वस्तु के लिए selfvtable ( वाइक पर विकी देखें ) को बायपास करने का एक तरीका प्रदान करता है । जिस तरह आप parent::methodName()किसी फ़ंक्शन के माता-पिता संस्करण को कॉल करने के लिए उपयोग कर सकते हैं , उसी तरह आप कॉल कर सकते हैं कॉल self::methodName()करने के लिए एक विधि के वर्तमान कक्षाएं।

class Person {
    private $name;

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

    public function getName() {
        return $this->name;
    }

    public function getTitle() {
        return $this->getName()." the person";
    }

    public function sayHello() {
        echo "Hello, I'm ".$this->getTitle()."<br/>";
    }

    public function sayGoodbye() {
        echo "Goodbye from ".self::getTitle()."<br/>";
    }
}

class Geek extends Person {
    public function __construct($name) {
        parent::__construct($name);
    }

    public function getTitle() {
        return $this->getName()." the geek";
    }
}

$geekObj = new Geek("Ludwig");
$geekObj->sayHello();
$geekObj->sayGoodbye();

यह आउटपुट होगा:

हेलो, आई एम लुडविग द गीक
गुडबाय फ्रॉम लुडविग द पर्सन

sayHello()$thisपॉइंटर का उपयोग करता है , इसलिए वाइबेट को कॉल करने के लिए आमंत्रित किया जाता है Geek::getTitle()sayGoodbye()का उपयोग करता है self::getTitle(), इसलिए व्यवहार्य उपयोग नहीं किया जाता है, और Person::getTitle()कहा जाता है। दोनों ही मामलों में, हम एक तात्कालिक वस्तु की विधि के साथ काम कर रहे हैं, और $thisकॉल किए गए कार्यों के भीतर पॉइंटर तक पहुंच है ।


3
यदि आप अपवाद के बजाय सामान्य नियम से शुरू करते हैं तो यह उत्तर और भी बेहतर होगा। यह तकनीकी विशेषज्ञता की नहीं, शैली की बात है। यह सबसे अच्छा उदाहरण है जो मैंने कभी स्वयं के बीच अंतर के बारे में देखा है :: और $ यह->, लेकिन यह छिपाने के लिए शर्म की बात है कि पहले एक धारणा को भंग करके।
adjwilli

3
@adjwilli: वह ख़राब स्टाइल क्यों है? क्या यह चेतना नहीं बढ़ाता है अगर ओपी की अपेक्षा (थीसिस) को पहले अस्वीकृत (प्रतिवाद) किया जाता है और फिर संश्लेषण के रूप में स्पष्टीकरण दिया जाता है?
हकर्रे

1
मुझे "वर्तमान वर्ग" वास्तव में समस्याग्रस्त लगता है। जैसा कि शब्द संयोजन को "वर्ग के रूप selfमें स्थित" / "वर्ग परिभाषा " के रूप में समझा जा सकता है, यह "वस्तु का वर्ग" (जो वास्तव में होगा static) का एक शाब्दिक हिस्सा है ।
जकुमी

किस बारे में $this::?
जेम्स

1
@ नाम - उपयोग करने का कोई अच्छा कारण नहीं है $this::; सभी संभावित मामलों को पहले से ही आमतौर पर उपयोग किए जाने वाले सिंटैक्स द्वारा कवर किया जाता है। तुम क्या मतलब है के आधार पर, उपयोग $this->, self::या static::
टूलमेकरसैट

461

उपयोग न करें self::, उपयोग करेंstatic::

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

class Person
{

    public static function status()
    {
        self::getStatus();
    }

    protected static function getStatus()
    {
        echo "Person is alive";
    }

}

अगर हम कहते हैं कि Person::status()हम देखेंगे "व्यक्ति जीवित है"। अब विचार करें कि जब हम एक ऐसा वर्ग बनाते हैं जो इससे विरासत में मिलता है:

class Deceased extends Person
{

    protected static function getStatus()
    {
        echo "Person is deceased";
    }

}

कॉलिंग से Deceased::status()हमें उम्मीद है कि "व्यक्ति मृतक है" लेकिन हम जो देख रहे हैं वह "व्यक्ति जीवित है" है क्योंकि कॉल को self::getStatus()परिभाषित करते समय गुंजाइश में मूल विधि परिभाषा होती है।

PHP 5.3 में एक समाधान है। static::संकल्प ऑपरेटर औजार "देर स्थिर बाइंडिंग" जो कह रही है कि यह वर्ग कहा जाता है की गुंजाइश के लिए बाध्य कर रहा है का एक आधुनिक तरीका है। में लाइन बदलें status()करने के लिए static::getStatus()और परिणाम आप क्या उम्मीद करेंगे कर रहे हैं। PHP के पुराने संस्करणों में आपको ऐसा करने के लिए एक कीचड़ ढूंढना होगा।

PHP प्रलेखन देखें

इसलिए पूछे गए सवाल का जवाब नहीं देने के लिए ...

$this->वर्तमान वस्तु (एक वर्ग का उदाहरण) static::को संदर्भित करता है , जबकि एक वर्ग को संदर्भित करता है


6
वर्ग स्थिरांक के बारे में क्या?
केविन बॉन्ड

53
"कॉलिंग डिक्स्ड :: स्टेटस () हम" पर्सन मृतक है "देखने की उम्मीद करेंगे"। नहीं। यह एक स्थैतिक फ़ंक्शन कॉल है इसलिए इसमें कोई बहुरूपता शामिल नहीं है।
cquezel 20

2
PHP की सभी खामियों में से, मुझे नहीं लगता कि यह सब पागल है। वे कैसे कोडर्स को वर्तमान वर्ग पर विधियों को नामित करने की अनुमति देंगे (जैसा कि उन्हें vtable में देखने के लिए विरोध किया गया है)? अगर उन्होंने इसे अलग नाम दिया (शायद अग्रणी अंडरस्कोर के साथ) तो जो लोग इस सुविधा को चाहते हैं, वे बदसूरत होने के लिए इसकी आलोचना करेंगे। इसके अलावा, जो भी संत नाम है, वे इसका उपयोग कर सकते हैं ऐसा लगता है कि हमेशा आसानी से भ्रमित लोग होंगे जो "पागल" व्यवहार के लिए इसकी आलोचना करेंगे, संभवत: इस बात से बेखबर कि कैसे विधि भी काम करती है।
tne

2
उदाहरण मुझे भ्रमित करने वाला लगता है: मैं getStatusविधि देखता हूं क्योंकि मैं एक वर्ग उदाहरण के लिए कहता हूं, एक वर्ग के लिए नहीं।
जानिस एल्मेरिस

1
@Sqoo - "स्वयं का उपयोग न करें ::, स्थैतिक का उपयोग न करें" कहने के लिए एक अजीब बिंदु है - वे जानबूझकर एक ही ऑपरेशन नहीं हैं। मुझे लगता है कि आप वास्तव में जो बिंदु बना रहे हैं वह "यह स्पष्ट है कि यदि आप 'सेल्फ ::' के बजाय वास्तविक वर्ग नाम 'MyClass ::' का उपयोग करते हैं । यही है, यदि आप चाहते हैं कि व्यवहार self::, आप इसे प्राप्त कर सकते हैं, कम। भ्रामक रूप से, विशिष्ट वर्ग के नाम का उपयोग करके, जैसे MyClass::
टूलमेकरसेव

248

वास्तव में यह समझने के लिए कि हम किस बारे में बात कर रहे हैं जब हम selfबनाम के बारे में बात करते हैं $this, तो हमें वास्तव में एक वैचारिक और व्यावहारिक स्तर पर क्या हो रहा है में खुदाई करने की आवश्यकता है। मैं वास्तव में किसी भी जवाब को उचित रूप से महसूस नहीं करता, इसलिए यहां मेरा प्रयास है।

चलो एक वर्ग और एक वस्तु क्या है के बारे में बात करके शुरू करते हैं ।

कक्षाएं और वस्तुओं, वैचारिक रूप से

तो, एक वर्ग क्या है ? बहुत सारे लोग इसे एक वस्तु के लिए खाका या टेम्पलेट के रूप में परिभाषित करते हैं । वास्तव में, आप PHP में यहाँ के बारे में अधिक पढ़ सकते हैं । और कुछ हद तक यह वास्तव में यही है। आइए एक वर्ग को देखें:

class Person {
    public $name = 'my name';
    public function sayHello() {
        echo "Hello";
    }
}

जैसा कि आप बता सकते हैं, उस वर्ग पर एक संपत्ति होती है जिसे कहा जाता है $nameऔर एक विधि (फ़ंक्शन) कहलाती है sayHello()

यह ध्यान रखना बहुत महत्वपूर्ण है कि वर्ग एक स्थिर संरचना है। जिसका अर्थ है कि वर्ग Person, जिसे एक बार परिभाषित किया गया है, हमेशा हर जगह वही होता है जो आप इसे देखते हैं।

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

$bob = new Person;
$adam = new Person;
$bob->name = 'Bob';
echo $adam->name; // "my name"

हम ऑपरेटर का उपयोग करके एक वर्ग के नए उदाहरण बनाते हैं new

इसलिए, हम कहते हैं कि एक वर्ग एक वैश्विक संरचना है, और एक वस्तु एक स्थानीय संरचना है। उस अजीब ->वाक्य रचना के बारे में चिंता न करें , हम थोड़ा सा उस में जाने जा रहे हैं।

एक अन्य बात जो हमें करनी चाहिए, वह यह है कि अगर कोई उदाहरण एक विशेष वर्ग है, तो हम जांच कर सकते हैं : यदि कोई उदाहरण वर्ग, या बच्चे का उपयोग करके बनाया गया था , तो वह बूलियन देता है ।instanceof$bob instanceof Person$bobPersonPerson

परिभाषित करने वाला राज्य

तो चलिए थोड़ा खुदाई करते हैं कि वास्तव में एक वर्ग क्या है। 5 प्रकार की "चीजें" होती हैं जिनमें एक वर्ग होता है:

  1. गुण - इन्हें चर समझें जो प्रत्येक उदाहरण में होगा।

    class Foo {
        public $bar = 1;
    }
  2. स्टैटिक प्रॉपर्टीज़ - इनको वैरिएबल समझें जो क्लास लेवल पर शेयर की जाती हैं। मतलब कि वे प्रत्येक उदाहरण द्वारा कभी भी कॉपी नहीं किए जाते हैं।

    class Foo {
        public static $bar = 1;
    }
  3. विधियाँ - ये ऐसे कार्य हैं जिनमें प्रत्येक उदाहरण में (और इंस्टेंस पर काम करना) होगा।

    class Foo {
        public function bar() {}
    }
  4. स्टैटिक मेथड्स - ये ऐसे फंक्शन हैं जिन्हें पूरी क्लास में शेयर किया जाता है। वे उदाहरणों पर काम नहीं करते हैं, बल्कि केवल स्थिर गुणों पर।

    class Foo {
        public static function bar() {}
    }
  5. स्थिरांक - वर्ग हल स्थिरांक। यहां कोई गहरा नहीं जा रहा है, लेकिन पूर्णता के लिए जोड़ना:

    class Foo {
        const BAR = 1;
    }

इसलिए मूल रूप से, हम स्थिर के बारे में "संकेत" का उपयोग करके वर्ग और ऑब्जेक्ट कंटेनर पर जानकारी संग्रहीत कर रहे हैं जो यह पहचानता है कि क्या जानकारी साझा की गई है (और इसलिए स्थिर) या नहीं (और इसलिए गतिशील)।

राज्य और तरीके

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

यदि किसी विधि को वैधानिक रूप से कहा जाता है, तो $thisचर को परिभाषित नहीं किया जाता है । ऐसा इसलिए है क्योंकि स्टैटिक कॉल के साथ कोई उदाहरण जुड़ा नहीं है।

यहां दिलचस्प बात यह है कि स्थिर कॉल कैसे किए जाते हैं। तो आइए बात करते हैं कि हम राज्य तक कैसे पहुँचें:

पहुंच राज्य

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

एक उदाहरण / कक्षा के बाहर से

एक उदाहरण / वर्ग के बाहर से, हमारे नियम काफी सरल और अनुमानित हैं। हमारे पास दो ऑपरेटर हैं, और प्रत्येक तुरंत हमें बताता है कि क्या हम एक उदाहरण या एक स्थिर वर्ग के साथ काम कर रहे हैं:

  • ->- ऑब्जेक्ट-ऑपरेटर - इसका उपयोग हमेशा तब किया जाता है जब हम किसी इंस्टेंस पर पहुँच रहे हों।

    $bob = new Person;
    echo $bob->name;

    यह ध्यान रखना महत्वपूर्ण है कि कॉलिंग का Person->fooकोई मतलब नहीं है (चूंकि Personएक वर्ग है, उदाहरण नहीं)। इसलिए, यह एक पार्स त्रुटि है।

  • ::- स्कोप-रिज़ॉल्यूशन-ऑपरेटर - इसका उपयोग हमेशा क्लास स्टैटिक प्रॉपर्टी या विधि तक पहुंचने के लिए किया जाता है।

    echo Foo::bar()

    इसके अतिरिक्त, हम एक वस्तु पर एक स्थिर विधि को उसी तरह से कॉल कर सकते हैं:

    echo $foo::bar()

    यह ध्यान रखना अत्यंत आवश्यक है कि जब हम बाहर से ऐसा करते हैं , तो वस्तु का उदाहरण bar()विधि से छिपा होता है । इसका मतलब है कि यह चलने के समान ही है:

    $class = get_class($foo);
    $class::bar();

इसलिए, $thisस्थिर कॉल में परिभाषित नहीं किया गया है।

एक उदाहरण / कक्षा के अंदर से

यहां चीजें थोड़ी बदल जाती हैं। एक ही ऑपरेटर का उपयोग किया जाता है, लेकिन उनका अर्थ काफी धुंधला हो जाता है।

वस्तु ऑपरेटर -> अभी भी वस्तु के उदाहरण राज्य के लिए कॉल करने के लिए प्रयोग किया जाता है।

class Foo {
    public $a = 1;
    public function bar() {
        return $this->a;
    }
}

ऑब्जेक्ट-ऑपरेटर का उपयोग करके bar()विधि $foo(उदाहरण Foo) पर कॉल करना : $foo->bar()उदाहरण के संस्करण में परिणाम देगा $a

तो ऐसी ही हम उम्मीद करते हैं।

::ऑपरेटर का अर्थ हालांकि बदल जाता है। यह वर्तमान फ़ंक्शन को कॉल के संदर्भ पर निर्भर करता है:

  • एक स्थिर संदर्भ के भीतर

    एक स्थिर संदर्भ के भीतर, किसी भी कॉल का उपयोग करके ::भी स्थिर हो जाएगा। आइए एक उदाहरण देखें:

    class Foo {
        public function bar() {
            return Foo::baz();
        }
        public function baz() {
            return isset($this);
        }
    }

    कॉलिंग विधि को सांख्यिकीय रूप Foo::bar()से कॉल करेगा baz(), और इसलिए आबादी नहीं$this होगी । यह ध्यान देने योग्य है कि PHP (5.3+) के हाल के संस्करणों में यह एक त्रुटि को ट्रिगर करेगा , क्योंकि हम गैर-स्थैतिक तरीकों को सांख्यिकीय रूप से बुला रहे हैं।E_STRICT

  • एक उदाहरण के संदर्भ में

    दूसरी ओर एक उदाहरण के संदर्भ में, कॉल का उपयोग कॉल ::के रिसीवर पर निर्भर करता है (जिस पद्धति से हम कॉल कर रहे हैं)। यदि विधि के रूप में परिभाषित किया गया है static, तो यह एक स्थिर कॉल का उपयोग करेगा। यदि यह नहीं है, तो यह उदाहरण की जानकारी को अग्रेषित करेगा।

    इसलिए, उपरोक्त कोड को देखकर, कॉलिंग $foo->bar()वापस आ जाएगी true, क्योंकि "स्थिर" कॉल एक उदाहरण के संदर्भ में होता है।

सही बात? ऐसा नहीं सोचा था। यह भ्रमित करने वाला है।

शॉर्ट-कट कीवर्ड

क्‍योंकि कक्षा के नामों का उपयोग करते हुए सब कुछ एकसाथ बांधना गंदा है, लेकिन PHP 3 मूल "शॉर्टकट" कीवर्ड प्रदान करता है जिससे गुंजाइश आसान हो जाती है।

  • self- यह वर्तमान वर्ग के नाम को संदर्भित करता है। तो self::baz()के रूप में ही है Foo::baz()के भीतर Fooवर्ग (इस पर कोई विधि)।

  • parent - यह वर्तमान वर्ग के माता-पिता को संदर्भित करता है।

  • static- यह संदर्भित वर्ग को संदर्भित करता है। वंशानुक्रम के लिए धन्यवाद, बाल कक्षाएं विधियों और स्थिर गुणों को ओवरराइड कर सकती हैं। इसलिए staticएक क्लास नाम के बजाय उन्हें कॉल करने से हमें यह हल करने की अनुमति मिलती है कि कॉल वर्तमान स्तर के बजाय कहां से आई है।

उदाहरण

इसे समझने का सबसे आसान तरीका कुछ उदाहरणों को देखना शुरू करना है। चलो एक वर्ग चुनें:

class Person {
    public static $number = 0;
    public $id = 0;
    public function __construct() {
        self::$number++;
        $this->id = self::$number;
    }
    public $name = "";
    public function getName() {
        return $this->name;
    }
    public function getId() {
        return $this->id;
    }
}

class Child extends Person {
    public $age = 0;
    public function __construct($age) {
        $this->age = $age;
        parent::__construct();
    }
    public function getName() {
        return 'child: ' . parent::getName();
    }
}

अब, हम यहाँ विरासत को भी देख रहे हैं। एक पल के लिए नजरअंदाज करें कि यह एक खराब वस्तु मॉडल है, लेकिन आइए देखें कि जब हम इसके साथ खेलते हैं तो क्या होता है:

$bob = new Person;
$bob->name = "Bob";
$adam = new Person;
$adam->name = "Adam";
$billy = new Child;
$billy->name = "Billy";
var_dump($bob->getId()); // 1
var_dump($adam->getId()); // 2
var_dump($billy->getId()); // 3

तो आईडी काउंटर दोनों उदाहरणों और बच्चों में साझा किया जाता है (क्योंकि हम इसे उपयोग selfकरने के लिए उपयोग कर रहे हैं । यदि हम उपयोग करते हैं static, तो हम इसे एक बच्चे की कक्षा में ओवरराइड कर सकते हैं)।

var_dump($bob->getName()); // Bob
var_dump($adam->getName()); // Adam
var_dump($billy->getName()); // child: Billy

ध्यान दें कि हम हर बार Person::getName() इंस्टेंस विधि को निष्पादित कर रहे हैं । लेकिन हम parent::getName()इसे एक मामले (बच्चे के मामले) में करने के लिए उपयोग कर रहे हैं । यह वही है जो इस दृष्टिकोण को शक्तिशाली बनाता है।

शब्द का सावधानी # 1

ध्यान दें कि यदि उदाहरण का उपयोग किया जाता है तो कॉलिंग संदर्भ निर्धारित करता है। इसलिए:

class Foo {
    public function isFoo() {
        return $this instanceof Foo;
    }
}

हमेशा सच नहीं होता है।

class Bar {
    public function doSomething() {
        return Foo::isFoo();
    }
}
$b = new Bar;
var_dump($b->doSomething()); // bool(false)

अब यहां वाकई अजीब है। हम एक अलग वर्ग को बुला रहे हैं, लेकिन $thisयह Foo::isFoo()विधि के लिए पारित हो जाता है $bar

यह सभी प्रकार के कीड़े और वैचारिक डब्ल्यूटीएफ-एरि का कारण बन सकता है। तो मैं अत्यधिक परहेज सुझाव देंगे ::उन तीन आभासी "शॉर्ट कट" कीवर्ड के अलावा कुछ पर उदाहरण के तरीकों के भीतर से ऑपरेटर ( static, self, और parent)।

शब्द का सावधानी # 2

ध्यान दें कि स्थिर तरीके और गुण सभी द्वारा साझा किए जाते हैं। यह उन्हें मूल रूप से वैश्विक चर बनाता है। ग्लोबल्स के साथ आने वाली सभी समान समस्याओं के साथ। इसलिए मैं वास्तव में स्थिर तरीकों / गुणों में जानकारी संग्रहीत करने में संकोच करूंगा जब तक कि आप इसके साथ सहज नहीं हो जाते जब तक कि यह वास्तव में वैश्विक नहीं हो।

शब्द # 3 सावधानी

सामान्य तौर पर आप इसका उपयोग करना चाहते हैं जिसे लेट-स्टैटिक-बाइंडिंग के रूप में जाना जाता staticहै self। लेकिन ध्यान दें कि वे एक ही चीज़ नहीं हैं, इसलिए यह कहना कि "हमेशा के staticबजाय उपयोग करना selfवास्तव में अदूरदर्शी है। इसके बजाय, उस कॉल के बारे में रोकें और सोचें जो आप करना चाहते हैं और सोचें कि क्या आप चाहते हैं कि बाल कक्षाएं उस स्थिर समाधान को ओवरराइड करने में सक्षम हों। कहते हैं।

टीएल / डॉ

बहुत बुरा, वापस जाओ और इसे पढ़ें। यह बहुत लंबा हो सकता है, लेकिन यह इतना लंबा है क्योंकि यह एक जटिल विषय है

टीएल / डीआर # 2

अच्छी बात है। संक्षेप में, एक वर्ग के भीतर वर्तमान वर्ग के नाम को संदर्भित करने के लिए selfउपयोग किया जाता है , जहां वर्तमान वस्तु उदाहरण के रूप में संदर्भित किया जाता है । ध्यान दें कि शॉर्ट-कट एक कॉपी / पेस्ट है। आप इसे सुरक्षित रूप से अपने वर्ग के नाम से बदल सकते हैं, और यह ठीक काम करेगा। लेकिन एक गतिशील चर है जो समय से पहले निर्धारित नहीं किया जा सकता है (और आपकी कक्षा भी नहीं हो सकती है)।$thisself$this

टीएल / डीआर # 3

यदि ऑब्जेक्ट-ऑपरेटर का उपयोग किया जाता है ( ->), तो आप हमेशा जानते हैं कि आप एक उदाहरण के साथ काम कर रहे हैं। यदि स्कोप-रिज़ॉल्यूशन-ऑपरेटर का उपयोग किया जाता है ( ::), आपको संदर्भ के बारे में अधिक जानकारी चाहिए (क्या हम ऑब्जेक्ट-संदर्भ में पहले से ही हैं? क्या हम ऑब्जेक्ट के बाहर हैं? आदि)।


1
शब्द का सावधानी # 1: $ यह स्थिर विधि को कॉल करते समय परिभाषित नहीं किया जाएगा: 3v4l.org/9kr0e
मार्क अची

ठीक है ... $thisपरिभाषित नहीं किया जाएगा यदि आप "सख्त मानक" का पालन करते हैं और विधियों को वैधानिक रूप से नहीं कहते हैं जो स्थिर के रूप में परिभाषित नहीं हैं। मैं यहां आपको समझाए गए परिणाम को देखता हूं: 3v4l.org/WeHVM सहमत हैं, वास्तव में अजीब है।
मार्क अची

2
लंबे विवरण को पूरी तरह से पढ़ने के बाद, मैंने इसे फिर से उभारने के लिए ऊपर स्क्रॉल करने के लिए आलसी महसूस किया। बस मजाक करते हुए, मैंने इसे बढ़ा दिया: डी। धन्यवाद यह बहुत उपयोगी है।
Mr_Green

3
स्व के बीच अंतर के बारे में एक स्पष्ट व्याख्या जोड़ना अच्छा होगा :: $ संपत्ति और स्व :: संपत्ति; मुझे लगता है कि यह काफी भ्रमित करने वाला है
टॉमसो बारबुगली

1
WoC # 1 PHP 7 के बाद से अलग व्यवहार करता है । जैसा कि Foo::isFoo()सांख्यिकीय रूप से कहा जाता है, $thisपरिभाषित नहीं किया जाएगा। मेरी राय में यह अधिक सहज व्यवहार है। - एक और अलग परिणाम दिया जाता है अगर Barसे विस्तार किया गया था Foo। तब कॉल Foo::isFoo()वास्तव में उदाहरण के संदर्भ में होगा (PHP7 के लिए विशिष्ट नहीं)।
Kontrollfreak

117

self(नहीं $ स्व) वर्ग के प्रकार को $thisसंदर्भित करता है , जहां कक्षा की वर्तमान आवृत्ति को संदर्भित करता है । selfस्थैतिक सदस्य कार्यों में उपयोग के लिए है ताकि आप स्थैतिक सदस्य चर का उपयोग कर सकें। $thisगैर-स्थैतिक सदस्य कार्यों में उपयोग किया जाता है, और उस वर्ग के उदाहरण का संदर्भ है जिस पर सदस्य फ़ंक्शन को बुलाया गया था।

क्योंकि thisएक वस्तु है, आप इसका उपयोग करते हैं जैसे:$this->member

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


97

$this-> एक वर्ग के चर (सदस्य चर) या विधियों के एक विशिष्ट उदाहरण को संदर्भित करने के लिए उपयोग किया जाता है।

Example: 
$derek = new Person();

$ derek अब व्यक्ति का एक विशिष्ट उदाहरण है। प्रत्येक व्यक्ति के पास पहले_नाम और अंतिम_नाम है, लेकिन $ derek के पास एक विशिष्ट first_name और last_name (डेरेक मार्टिन) है। $ डेरेक उदाहरण के अंदर, हम उन लोगों को इस $ के रूप में संदर्भित कर सकते हैं-> first_name और $ this-> last_name

ClassName :: का उपयोग उस प्रकार के वर्ग, और उसके स्थिर चर, स्थिर विधियों को संदर्भित करने के लिए किया जाता है। यदि यह मदद करता है, तो आप "स्थिर" शब्द को "साझा" के साथ मानसिक रूप से बदल सकते हैं। क्योंकि वे साझा किए जाते हैं, वे $ इसे संदर्भित नहीं कर सकते, जो एक विशिष्ट उदाहरण (साझा नहीं) को संदर्भित करता है। स्थैतिक चर (यानी स्थिर $ db_connection) को एक प्रकार की वस्तु के सभी उदाहरणों के बीच साझा किया जा सकता है। उदाहरण के लिए, सभी डेटाबेस ऑब्जेक्ट एक कनेक्शन (स्थिर $ कनेक्शन) साझा करते हैं।

स्थैतिक चर उदाहरण: Pretend हमारे पास एक एकल सदस्य चर के साथ एक डेटाबेस वर्ग है: स्थैतिक $ num_connections; अब, इसे कंस्ट्रक्टर में डालें:

function __construct()
{
    if(!isset $num_connections || $num_connections==null)
    {
        $num_connections=0;
    }
    else
    {
        $num_connections++;
    }
}

जिस तरह वस्तुओं में कंस्ट्रक्टर होते हैं, उनके पास भी विध्वंसक होते हैं, जो तब निष्पादित होते हैं जब ऑब्जेक्ट मर जाता है या परेशान होता है:

function __destruct()
{
    $num_connections--;
}

हर बार जब हम एक नया उदाहरण बनाते हैं, तो यह हमारे कनेक्शन काउंटर को एक बढ़ा देगा। हर बार जब हम एक इंस्टेंस का उपयोग करते हुए नष्ट या बंद कर देते हैं, तो यह कनेक्शन काउंटर को एक से कम कर देगा। इस तरह, हम उस डेटाबेस ऑब्जेक्ट के उदाहरणों की संख्या की निगरानी कर सकते हैं जिसका हमारे पास उपयोग है:

echo DB::num_connections;

क्योंकि $ num_connections स्थिर (साझा) है, यह सक्रिय डेटाबेस ऑब्जेक्ट्स की कुल संख्या को प्रतिबिंबित करेगा। आपने डेटाबेस वर्ग के सभी उदाहरणों के बीच डेटाबेस कनेक्शन साझा करने के लिए उपयोग की जाने वाली इस तकनीक को देखा होगा। ऐसा इसलिए किया जाता है क्योंकि डेटाबेस कनेक्शन बनाने में एक लंबा समय लगता है, इसलिए यह सिर्फ एक बनाने के लिए सबसे अच्छा है, और इसे साझा करें (इसे एक एकल पैटर्न कहा जाता है)।

स्टेटिक मेथड्स (अर्थात सार्वजनिक स्थैतिक दृश्य :: format_phone_number ($ अंक)) का उपयोग उन वस्तुओं में से किसी एक को तत्काल पहले करने के बिना किया जा सकता है (अर्थात वे आंतरिक रूप से इस $ का संदर्भ नहीं देते हैं)।

स्थैतिक विधि उदाहरण:

public static function prettyName($first_name, $last_name)
{
    echo ucfirst($first_name).' '.ucfirst($last_name);
}

echo Person::prettyName($derek->first_name, $derek->last_name);

जैसा कि आप देख सकते हैं, सार्वजनिक स्थैतिक फ़ंक्शन prettyName वस्तु के बारे में कुछ भी नहीं जानता है। यह सिर्फ आपके द्वारा पास किए जाने वाले मापदंडों के साथ काम कर रहा है, जैसे कि एक सामान्य फ़ंक्शन जो किसी ऑब्जेक्ट का हिस्सा नहीं है। परेशान क्यों, अगर हम सिर्फ वस्तु के हिस्से के रूप में नहीं कर सकते थे?

  1. पहले, कार्यों को ऑब्जेक्ट में संलग्न करना आपको चीजों को व्यवस्थित रखने में मदद करता है, इसलिए आप जानते हैं कि उन्हें कहां खोजना है।
  2. दूसरा, यह नामकरण संघर्ष को रोकता है। एक बड़ी परियोजना में, आपको दो डेवलपर्स गेटनेम () फ़ंक्शन बनाने की संभावना है। यदि कोई ClassName1 :: getName () बनाता है, और दूसरा ClassName2 :: getName () बनाता है, तो यह कोई समस्या नहीं है। कोई विवाद नहीं। याय स्थैतिक विधियाँ!

SELF :: यदि आप उस ऑब्जेक्ट के बाहर कोडिंग कर रहे हैं जिसमें वह स्थिर विधि है जिसे आप संदर्भित करना चाहते हैं, तो आपको उसे ऑब्जेक्ट के नाम का उपयोग करके कॉल करना होगा देखें :: format_phone_number ($ phone_number); यदि आप उस ऑब्जेक्ट के अंदर कोडिंग कर रहे हैं जिसमें वह स्टैटिक विधि है जिसे आप संदर्भित करना चाहते हैं, तो आप ऑब्जेक्ट के नाम का उपयोग कर सकते हैं देखें :: format_phone_number ($ pn), या आप स्वयं का उपयोग कर सकते हैं :: format_phone_number ($ nn) शॉर्टकट

वही स्थिर वैरिएबल के लिए जाता है: उदाहरण: दृश्य :: टेम्पलेट्स_पथ बनाम स्व :: टेम्पलेट्स_पथ

डीबी वर्ग के अंदर, अगर हम किसी अन्य वस्तु के स्थिर तरीके की बात कर रहे थे, तो हम ऑब्जेक्ट के नाम का उपयोग करेंगे: उदाहरण: सत्र :: getUserOnline ();

लेकिन अगर डीबी वर्ग अपने स्वयं के स्थिर चर को संदर्भित करना चाहता था, तो यह स्वयं कहेगा: उदाहरण: आत्म :: कनेक्शन;

आशा है कि स्पष्ट चीजों में मदद करता है :)


बहुत बढ़िया जवाब। मैं केवल इंगित करना चाहता हूं, जब एक स्थिर विशेषता का उल्लेख करते हैं, तो आपको एक $संकेत का उपयोग करने की आवश्यकता होती है । उदाहरण के लिएself::$templates_path
henrywright

30

से इस ब्लॉग पोस्ट :

  • self वर्तमान वर्ग को संदर्भित करता है
  • self स्थिर कार्यों और संदर्भ स्थैतिक सदस्य चर को संदर्भित करने के लिए उपयोग किया जा सकता है
  • self स्थिर कार्यों के अंदर इस्तेमाल किया जा सकता है
  • self विटेबल को दरकिनार करके बहुरूपी व्यवहार को भी बंद कर सकता है
  • $this वर्तमान वस्तु को संदर्भित करता है
  • $this स्थिर कार्यों को कॉल करने के लिए इस्तेमाल किया जा सकता है
  • $thisस्थिर सदस्य चर को कॉल करने के लिए उपयोग नहीं किया जाना चाहिए। selfइसके बजाय उपयोग करें ।
  • $this स्थिर कार्यों के अंदर उपयोग नहीं किया जा सकता है

26

PHP में, आप स्थैतिक गुणों और विधियों का उपयोग करने के लिए स्व कीवर्ड का उपयोग करते हैं।

समस्या यह है कि आप कहीं $this->method()से self::method()भी प्रतिस्थापित कर सकते हैं , भले ही method()उसे स्थैतिक घोषित किया गया हो या नहीं। तो आपको किसका उपयोग करना चाहिए?

इस कोड पर विचार करें:

class ParentClass {
    function test() {
        self::who();    // will output 'parent'
        $this->who();   // will output 'child'
    }

    function who() {
        echo 'parent';
    }
}

class ChildClass extends ParentClass {
    function who() {
        echo 'child';
    }
}

$obj = new ChildClass();
$obj->test();

इस उदाहरण में, self::who()हमेशा 'पैरेंट' को आउटपुट करेगा, जबकि $this->who()ऑब्जेक्ट किस क्लास पर निर्भर करेगा।

अब हम देख सकते हैं कि आत्म उस वर्ग को संदर्भित करता है जिसमें इसे कहा जाता है, जबकि वर्तमान वस्तु$this के वर्ग को संदर्भित करता है ।

इसलिए, आपको स्वयं का उपयोग तब ही करना चाहिए जब $thisउपलब्ध नहीं है, या जब आप वंशजों को वर्तमान पद्धति को अधिलेखित करने की अनुमति नहीं देना चाहते हैं।


22

एक वर्ग परिभाषा के अंदर, $thisवर्तमान वस्तु को संदर्भित करता है, जबकिself संदर्भित करता है वर्तमान वर्ग को संदर्भित करता है।

उपयोग करने वाले एक वर्ग तत्व को संदर्भित करना आवश्यक है self, और उपयोग करने वाले किसी वस्तु तत्व को संदर्भित करना है $this

self::STAT // refer to a constant value
self::$stat // static variable
$this->stat // refer to an object variable  

21

यहाँ $ के सही उपयोग का एक उदाहरण है और गैर-स्थैतिक और स्थिर सदस्य चर के लिए स्व:

<?php
class X {
    private $non_static_member = 1;
    private static $static_member = 2;

    function __construct() {
        echo $this->non_static_member . ' '
           . self::$static_member;
    }
}

new X();
?> 

21

Http://www.php.net/manual/en/language.oop5.static.php के अनुसार नहीं है $self। केवल $thisवर्ग (वस्तु), और स्वयं के वर्तमान उदाहरण का उल्लेख करने के लिए है, जिसका उपयोग किसी वर्ग के स्थिर सदस्यों को संदर्भित करने के लिए किया जा सकता है। एक वस्तु उदाहरण और एक वर्ग के बीच का अंतर यहाँ खेलने में आता है।


9
सुझाव: एसिड पर ट्रिपिंग करते समय इस उत्तर को पढ़ें।
a20

16

मेरा मानना ​​है कि प्रश्न यह नहीं था कि क्या आप कक्षा के स्थिर सदस्य को कॉल करके बता सकते हैं ClassName::staticMember। सवाल यह था कि उपयोग करने self::classmemberऔर के बीच अंतर क्या है$this->classmember

उदाहरण के लिए, निम्नलिखित दोनों उदाहरण बिना किसी त्रुटि के काम करते हैं, चाहे आप उपयोग करें self::या$this->

class Person{
    private $name;
    private $address;

    public function __construct($new_name,$new_address){
        $this->name = $new_name;
        $this->address = $new_address;
    }
}

class Person{
    private $name;
    private $address;
    public function __construct($new_name,$new_address){
        self::$name = $new_name;
        self::$address = $new_address;
    }
}

यह विशेष रूप से मज़ेदार है कि आप अपना उत्तर "मुझे विश्वास है कि सवाल यह था कि क्या आप ClassName :: staticMember कॉल करके वर्ग के स्थिर सदस्य को कॉल कर सकते हैं, के साथ शुरू करते हैं। सवाल यह है कि स्वयं का उपयोग करने के बीच का अंतर क्या है :: classmember और $ this-> classmember" और फिर आप बिना किसी मतभेद के आगे बढ़ना चाहते हैं। वास्तव में, आप एक उदाहरण दिखाते हैं कि दो विकल्प कहाँ काम करते हैं। -1
बटल बटुक 10

फिर भी उपयोगी। गुंजाइश रिज़ॉल्यूशन के बारे में थी और यह हिस्सा php मैनुअल में स्पष्ट नहीं है। मुझे अभी भी यह उपयोगी लगता है
renairb

2
Fatal error: Access to undeclared static property: Person::$name in D:\LAMP\www\test.php on line 16
के-गन

16

self वर्तमान वर्ग को संदर्भित करता है (जिसमें इसे कहा जाता है),

$thisवर्तमान वस्तु को संदर्भित करता है। आप स्वयं के बजाय स्थैतिक का उपयोग कर सकते हैं। उदाहरण देखें:

    class ParentClass {
            function test() {
                    self::which();  // output 'parent'
                    $this->which(); // output 'child'
            }

            function which() {
                    echo 'parent';
            }
    }

    class ChildClass extends ParentClass {
            function which() {
                    echo 'child';
            }
    }

    $obj = new ChildClass();
    $obj->test();

आउटपुट: माता-पिता का बच्चा


16
  • ऑब्जेक्ट पॉइंटर $thisवर्तमान ऑब्जेक्ट को संदर्भित करता है।
  • वर्ग मान staticवर्तमान वस्तु को संदर्भित करता है।
  • वर्ग मान से selfतात्पर्य उस सटीक वर्ग से है जिसे इसमें परिभाषित किया गया था।
  • वर्ग मान से parentतात्पर्य उस सटीक वर्ग के माता-पिता से है जिसे इसमें परिभाषित किया गया था।

निम्नलिखित उदाहरण देखें जो ओवरलोडिंग दिखाता है।

<?php

class A {

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

    public static function newSelfClass()
    {
        return new self;
    }

    public function newThisClass()
    {
        return new $this;
    }
}

class B extends A
{
    public function newParentClass()
    {
        return new parent;
    }
}


$b = new B;

var_dump($b::newStaticClass()); // B
var_dump($b::newSelfClass()); // A because self belongs to "A"
var_dump($b->newThisClass()); // B
var_dump($b->newParentClass()); // A


class C extends B
{
    public static function newSelfClass()
    {
        return new self;
    }
}


$c = new C;

var_dump($c::newStaticClass()); // C
var_dump($c::newSelfClass()); // C because self now points to "C" class
var_dump($c->newThisClass()); // C
var_dump($b->newParentClass()); // A because parent was defined *way back* in class "B"

अधिकांश समय आप वर्तमान वर्ग को संदर्भित करना चाहते हैं, यही कारण है कि आप इसका उपयोग करते हैं staticया $this। हालाँकि, ऐसे समय होते हैं जब आपको आवश्यकता होती है self क्योंकि आप चाहते हैं कि मूल वर्ग जो चाहे उसे विस्तारित करे। (बहुत, बहुत ही कम)


14

जैसा कि यहां किसी ने प्रदर्शन के बारे में बात नहीं की, यहां एक छोटा बेंचमार्क है जो मैंने किया था (5.6):

 Name     | Time    | Percent  
----------|---------|---------  
 $this->  | 0.99163 | 106.23%  
 self::   | 0.96912 | 103.82%  
 static:: | 0.93348 | 100%

वे 2 000 000 रन के परिणाम हैं, और यहां वह कोड है जिसका मैंने उपयोग किया है:

<?php

require '../vendor/autoload.php';

// My small class to do benchmarks
// All it does is looping over every test x times and record the
//   time it takes using `microtime(true)`
// Then, the percentage is calculated, with 100% being the quickest
// Times are being rouned for outputting only, not to calculate the percentages
$b = new Tleb\Benchmark\Benchmark(2000000);

class Foo
{
    public function calling_this()
    {
        $this->called();
    }

    public function calling_self()
    {
        self::called();
    }

    public function calling_static()
    {
        static::called();
    }

    public static function called()
    {
    }
}

$b->add('$this->',  function () { $foo = new Foo; $foo->calling_this(); });
$b->add('self::',   function () { $foo = new Foo; $foo->calling_self(); });
$b->add('static::', function () { $foo = new Foo; $foo->calling_static(); });

$b->run();

1
No-op function को कॉल करना 2 000 000 बार 1s रहता है। होगा प्यार PHP।
rr-

अच्छा पुराना PHP। :) लेकिन एक कॉल = 0.001ms। क्या यह बुरा है?
tleb

मेरा मानना ​​है कि यह (और इसी तरह की चीजें) यही कारण है कि ORMs जैसी चीजें तब तक धीमी लगती हैं जब तक आप सामान नहीं करते हैं, और स्थैतिक साइट जनरेटर एक चीज है।
rr-

2
इसे सैद्धांतिक रूप से 1 प्रोसेसर घड़ी चक्र लेना चाहिए, जो 1 / 2e9 s = 0.5 nsइन दिनों बनाता है
बडी

बस मेरा जवाब फिर से पढ़ें। सावधान रहें: यह कक्षा भी बनाता है। मुझे नहीं पता कि मैंने useकीवर्ड tbh का उपयोग क्यों नहीं किया है , लेकिन मेरे पास एक बेंचमार्क को फिर से बनाने के लिए PHP नहीं है, और मुझे वास्तव में इसे पुनः स्थापित करने का मन नहीं है।
tleb

13

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


8

मैं एक ही सवाल में भाग गया और सरल उत्तर है:

  • $this वर्ग के एक उदाहरण की आवश्यकता है
  • self:: नहीं है

जब भी आप स्थैतिक विधियों या स्थिर विशेषताओं का उपयोग कर रहे हैं और उन्हें तुरंत self:कॉल करने के लिए उपयोग करने की $thisआवश्यकता है , तो उन्हें तुरंत कॉल करने के लिए उपयोग किए जाने वाले वर्ग की वस्तु के बिना कॉल करना चाहते हैं ।


7

$thisवर्तमान क्लास ऑब्जेक्ट को selfसंदर्भित करता है, वर्तमान क्लास को संदर्भित करता है (ऑब्जेक्ट नहीं)। वर्ग वस्तु का खाका है। तो आप एक वर्ग को परिभाषित करते हैं, लेकिन आप वस्तुओं का निर्माण करते हैं।

तो दूसरे शब्दों में, उपयोग self for staticऔरthis for none-static members or methods

बच्चे / माता-पिता परिदृश्य में self / parentभी ज्यादातर बच्चे और माता-पिता वर्ग के सदस्यों और विधियों की पहचान करने के लिए उपयोग किया जाता है।


7

इसके अतिरिक्त $this::अभी तक चर्चा नहीं हुई है।

केवल सूचना के प्रयोजनों के लिए, PHP 5.3 के रूप में जब वर्तमान गुंजाइश मान प्राप्त करने के लिए तात्कालिक वस्तुओं के साथ काम कर रहा है, जैसा कि उपयोग करने के लिए विरोध किया जाता है static::, कोई वैकल्पिक रूप से उपयोग कर सकता $this::है।

http://ideone.com/7etRHy

class Foo
{
    const NAME = 'Foo';

    //Always Foo::NAME (Foo) due to self
    protected static $staticName = self::NAME;

    public function __construct()
    {
        echo $this::NAME;
    }

    public function getStaticName()
    {
       echo $this::$staticName;
    }
}

class Bar extends Foo
{
    const NAME = 'FooBar';

    /**
     * override getStaticName to output Bar::NAME
     */
    public function getStaticName()
    {
        $this::$staticName = $this::NAME;
        parent::getStaticName();
    }
}

$foo = new Foo; //outputs Foo
$bar = new Bar; //outputs FooBar
$foo->getStaticName(); //outputs Foo
$bar->getStaticName(); //outputs FooBar
$foo->getStaticName(); //outputs FooBar

ऊपर दिए गए कोड का उपयोग करना सामान्य या अनुशंसित अभ्यास नहीं है, लेकिन बस इसके उपयोग को स्पष्ट करना है, और क्या "क्या आप जानते हैं?" मूल पोस्टर के प्रश्न के संदर्भ में।

यह भी $object::CONSTANTउदाहरण के लिए echo $foo::NAME;विरोध के रूप में उपयोग का प्रतिनिधित्व करता है$this::NAME;


5

का प्रयोग करें selfअगर आप उस वर्ग की एक वस्तु / उदाहरण बनाकर बिना एक वर्ग की एक विधि कॉल करने के लिए, इस प्रकार की बचत चाहते रैम (कभी कभी उस उद्देश्य के लिए स्वयं का उपयोग करें)। दूसरे शब्दों में, यह वास्तव में एक विधि को सांख्यिकीय रूप से बुला रहा है। thisऑब्जेक्ट परिप्रेक्ष्य के लिए उपयोग करें ।


2

केस 1: का उपयोग selfकक्षा में रहने वालों के लिए किया जा सकता है

 क्लास क्लास { 
     const FIXED_NUMBER = 4; 
     स्वयं :: POUNDS_TO_KILOGRAMS
}

यदि आप इसे कक्षा के बाहर बुलाना चाहते हैं, तो उपयोग करें classA::POUNDS_TO_KILOGRAMS तो स्थिरांक का उपयोग करें

केस 2: स्थैतिक गुणों के लिए

क्लास क्लास {
     सार्वजनिक समारोह __construct () { 
     स्वयं :: $ _ काउंटर ++; $ यह-> संख्या = स्व :: $ _ काउंटर;
   }
}

1

Php.net के अनुसार इस संदर्भ में तीन विशेष कीवर्ड होते हैं: self, parentऔर static। उनका उपयोग वर्ग परिभाषा के अंदर से गुणों या विधियों तक पहुंचने के लिए किया जाता है।

$thisदूसरी ओर, किसी भी वर्ग के उदाहरण और तरीकों को कॉल करने के लिए उपयोग किया जाता है जब तक कि वह वर्ग सुलभ न हो।


-1

स्वयं ::  वर्तमान वर्ग के लिए उपयोग किया जाने वाला कीवर्ड और मूल रूप से इसका उपयोग स्थैतिक सदस्यों, विधियों और स्थिरांक तक पहुंचने के लिए किया जाता है। लेकिन $ के मामले में आप स्थैतिक सदस्य, विधि और कार्यों को कॉल नहीं कर सकते।

आप किसी अन्य वर्ग में स्व :: कीवर्ड का उपयोग कर सकते हैं और स्थिर सदस्यों, विधि और स्थिरांक का उपयोग कर सकते हैं । जब यह इस कीवर्ड के मामले में मूल वर्ग से समान होगा और समान होगा । आप गैर-स्थिर सदस्यों, विधि और फ़ंक्शन को किसी अन्य वर्ग में एक्सेस कर सकते हैं, जब यह मूल वर्ग से निकाला जाएगा।

नीचे दिया गया कोड स्वयं का एक उदाहरण है :: और इस खोजशब्द $ । बस अपनी कोड फ़ाइल में कोड को कॉपी और पेस्ट करें और आउटपुट देखें।

class cars{
    var $doors=4;   
    static $car_wheel=4;

  public function car_features(){
    echo $this->doors." Doors <br>";
    echo self::$car_wheel." Wheels <br>"; 
  }
}

class spec extends cars{
    function car_spec(){
        print(self::$car_wheel." Doors <br>");
        print($this->doors." Wheels <br>");
    }
}

/********Parent class output*********/

$car = new cars;
print_r($car->car_features());

echo "------------------------<br>";

/********Extend class from another class output**********/


$car_spec_show=new spec;

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