जवाबों:
PHP मेनुअल में आपको लेट स्टैटिक बाइंडिंग को जरूर पढ़ना चाहिए । हालाँकि, मैं आपको एक त्वरित सारांश देने की कोशिश करूँगा।
मूल रूप से, यह इस तथ्य से उबलता है कि self
कीवर्ड विरासत के समान नियमों का पालन नहीं करता है। self
हमेशा उस कक्षा में हल करता है जिसमें इसका उपयोग किया जाता है। इसका मतलब यह है कि यदि आप किसी अभिभावक वर्ग में एक विधि बनाते हैं और उसे बच्चे की कक्षा से बुलाते हैं, self
तो बच्चे का संदर्भ नहीं देंगे जैसा कि आप उम्मीद कर सकते हैं।
लेट स्टैटिक बाइंडिंग static
कीवर्ड के लिए एक नया प्रयोग प्रस्तुत करता है, जो इस विशेष कमी को संबोधित करता है। जब आप उपयोग static
करते हैं , तो यह उस वर्ग का प्रतिनिधित्व करता है जहां आप पहली बार इसका उपयोग करते हैं, अर्थात। यह रनटाइम क्लास को 'बांधता' है।
इसके पीछे दो बुनियादी अवधारणाएँ हैं। जिस तरह से self
, parent
और static
जब static
खेल में होता है, तब काम किया जा सकता है, इसलिए इसे और अधिक विस्तार से जाने के बजाय, मैं दृढ़ता से अनुशंसा करूंगा कि आप मैनुअल वीडियो उदाहरणों का अध्ययन करें। एक बार जब आप प्रत्येक कीवर्ड की मूल बातें समझ लेते हैं, तो उदाहरण देखने के लिए बहुत आवश्यक होते हैं कि आपको किस प्रकार के परिणाम मिलने वाले हैं।
self
कीवर्ड वंशानुक्रम के नियमों का पालन नहीं करता है। self
हमेशा उस वर्ग का समाधान करता है जिसमें इसका उपयोग किया जाता है।" - इसका मतलब यह नहीं है कि आप किसी self
गैर-स्टैटिक विधियों की तरह, किसी चाइल्ड ऑब्जेक्ट से माता-पिता की स्टेटिक विधि को नहीं कह सकते । आप शायद सही बात का मतलब है, लेकिन आप फिर से वाक्यांश होना चाहिए। यह सब वास्तव में केवल एक बार मायने रखता है जब बच्चों ने पहचान के सदस्यों का नाम लिया है क्योंकि आप तब यह तय कर सकते हैं कि किन लोगों को static::
इसके बजाय उपयोग करना है।
से पीएचपी: स्वर्गीय स्टेटिक बाइंडिंग - मैनुअल :
PHP 5.3.0 के रूप में, PHP में लेटैटिक स्टैटिक बाइंडिंग नामक एक फीचर लागू होता है, जिसे स्टैटिक इनहेरिटेंस के संदर्भ में क्लास को संदर्भित करने के लिए इस्तेमाल किया जा सकता है।
लेट स्टैटिक बाइंडिंग उस सीमा को हल करने की कोशिश करता है जिसमें एक कीवर्ड पेश किया जाता है जो उस क्लास को संदर्भित करता है जिसे शुरू में रनटाइम पर बुलाया गया था। ... यह एक नया कीवर्ड शुरू नहीं करने का निर्णय लिया गया था, बल्कि इसका उपयोग
static
पहले से ही आरक्षित था।
आइए एक उदाहरण देखें:
<?php
class Car
{
public static function run()
{
return static::getName();
}
private static function getName()
{
return 'Car';
}
}
class Toyota extends Car
{
public static function getName()
{
return 'Toyota';
}
}
echo Car::run(); // Output: Car
echo Toyota::run(); // Output: Toyota
?>
देर से स्थिर बाइंडिंग अंतिम "गैर-अग्रेषण कॉल" नाम के वर्ग को संग्रहीत करके काम करता है। स्थैतिक विधि कॉल के मामले में, यह स्पष्ट रूप से नामित वर्ग है (आमतौर पर
::
ऑपरेटर के बाईं ओर ); गैर-स्थैतिक विधि कॉल के मामले में, यह ऑब्जेक्ट का वर्ग है। एक "अग्रेषण कॉल" एक स्थिर एक है कि द्वारा शुरू की गई हैself::
,parent::
,static::
, या, यदि वर्ग पदानुक्रम में ऊपर जा रहा है,forward_static_call()
। फ़ंक्शनget_called_class()
का उपयोग बुलाए गए वर्ग के नाम के साथ एक स्ट्रिंग को पुनः प्राप्त करने के लिए किया जा सकता है औरstatic::
इसके दायरे का परिचय दे सकता है।
बहुत स्पष्ट व्यवहार नहीं है:
निम्नलिखित कोड 'अल्फ़ाबेटा' का निर्माण करता है।
class alpha {
function classname(){
return __CLASS__;
}
function selfname(){
return self::classname();
}
function staticname(){
return static::classname();
}
}
class beta extends alpha {
function classname(){
return __CLASS__;
}
}
$beta = new beta();
echo $beta->selfname(); // Output: alpha
echo $beta->staticname(); // Output: beta
हालांकि, यदि हम बीटा वर्ग से क्लासनाम फ़ंक्शन की घोषणा को हटाते हैं, तो हमें परिणाम के रूप में 'अल्फ़ाल्फा' मिलता है।
मैं पुस्तक से उद्धृत कर रहा हूँ: "PHP मास्टर अत्याधुनिक लेखन"।
लेट स्टैटिक बाइंडिंग php 5.3 के साथ पेश किया गया एक फीचर था। यह हमें माता-पिता वर्ग से स्थिर तरीकों को विरासत में लेने की अनुमति देता है, और बच्चे के वर्ग को बुलाया जाता है।
इसका मतलब है कि आपके पास स्थैतिक विधियों के साथ एक सार वर्ग हो सकता है, और स्वयं :: विधि () के बजाय स्थैतिक :: विधि () संकेतन का उपयोग करके बाल वर्ग के ठोस कार्यान्वयन को संदर्भित कर सकता है ।
बेझिझक आधिकारिक php प्रलेखन पर एक नज़र डालें: http://php.net/manual/en/language.oop5.late-static-bindings.php
लेट स्टेटिक बाइंडिंग को स्पष्ट करने का सबसे स्पष्ट तरीका एक सरल उदाहरण है। नीचे दिए गए दो वर्ग परिभाषाओं पर एक नज़र डालें और पढ़ें।
class Vehicle {
public static function invokeDriveByStatic() {
return static::drive(); // Late Static Binding
}
public static function invokeStopBySelf() {
return self::stop(); // NOT Late Static Binding
}
private static function drive(){
return "I'm driving a VEHICLE";
}
private static function stop(){
return "I'm stopping a VEHICLE";
}
}
class Car extends Vehicle {
protected static function drive(){
return "I'm driving a CAR";
}
private static function stop(){
return "I'm stopping a CAR";
}
}
हम एक अभिभावक वर्ग (वाहन) और एक बाल वर्ग (कार) देखते हैं। जनक वर्ग में 2 सार्वजनिक विधियाँ हैं:
invokeDriveByStatic
invokeStopBySelf
पैरेंट क्लास में 2 निजी तरीके भी हैं:
drive
stop
चाइल्ड क्लास 2 तरीकों से आगे निकल जाता है:
drive
stop
अब सार्वजनिक तरीकों को लागू करते हैं:
invokeDriveByStatic
invokeStopBySelf
खुद से पूछें: कौन सा वर्ग आक्रमण करता है invokeDriveByStatic
/ invokeStopBySelf
? जनक या बाल वर्ग?
नीचे एक नज़र डालें:
// This is NOT Late Static Binding
// Parent class invokes from Parent. In this case Vehicle.
echo Vehicle::invokeDriveByStatic(); // I'm driving a VEHICLE
echo Vehicle::invokeStopBySelf(); // I'm stopping a VEHICLE
// !!! This is Late Static Binding !!!!
// Child class invokes an inherited method from Parent.
// Child class = Car, Inherited method = invokeDriveByStatic().
// The inherited method invokes a method that is overridden by the Child class.
// Overridden method = drive()
echo Car::invokeDriveByStatic(); // I'm driving a CAR
// This is NOT Late Static Binding
// Child class invokes an inherited method from Parent.
// The inherited method invokes a method inside the Vehicle context.
echo Car::invokeStopBySelf(); // I'm stopping a VEHICLE
static
कीवर्ड एक सिंगलटन डिजाइन पैटर्न में प्रयोग किया जाता है। लिंक देखें: https://refactoring.guru/design-patterns/singleton/php/example
अंतर दिखाने के लिए सबसे सरल उदाहरण।
नोट, स्व :: $ c
class A
{
static $c = 7;
public static function getVal()
{
return self::$c;
}
}
class B extends A
{
static $c = 8;
}
B::getVal(); // 7
देर से स्थिर बंधन, नोट स्थिर :: $ c
class A
{
static $c = 7;
public static function getVal()
{
return static::$c;
}
}
class B extends A
{
static $c = 8;
}
B::getVal(); // 8
यह भी देखें कि क्या आप बाल कक्षाओं में स्थिर चर अद्यतन करते हैं। मुझे यह (कुछ) अप्रत्याशित परिणाम मिला जहां बच्चा बी बच्चे को सी अपडेट करता है:
class A{
protected static $things;
}
class B extends A {
public static function things(){
static::$things[1] = 'Thing B';
return static::$things;
}
}
class C extends A{
public static function things(){
static::$things[2] = 'Thing C';
return static::$things;
}
}
print_r(C::things());
// Array (
// [2] => Thing C
// )
B::things();
print_r(C::things());
// Array (
// [2] => Thing C
// [1] => Thing B
// )
आप प्रत्येक चाइल्ड क्लास में उसी चर को घोषित करके इसे ठीक कर सकते हैं, उदाहरण के लिए:
class C extends A{
protected static $things; // add this and B will not interfere!
public static function things(){
static::$things[2] = 'Thing C';
return static::$things;
}
}