आपने अभी-अभी एक नया Laravel एप्लीकेशन इंस्टॉल किया है, इसे बूट किया है, और स्वागत पृष्ठ प्राप्त किया है। हर किसी की तरह, आप यह देखने की कोशिश करते हैं कि यह कैसे रेंडर किया गया है, इसलिए आप फ़ाइल में जाते हैं और इस कोड का सामना करते हैं: web.php <?php use Illuminate\Support\Facades\Route; Route::get('/', function () { return view('welcome'); }); यह स्पष्ट है कि हमें स्वागत दृश्य कैसे मिला, लेकिन आप इस बारे में उत्सुक हैं कि लारवेल का राउटर कैसे काम करता है, इसलिए आप कोड में गोता लगाने का फैसला करते हैं। प्रारंभिक धारणा यह है: एक क्लास है जिस पर हम एक स्थिर विधि कॉल कर रहे हैं। हालाँकि, इसे क्लिक करने पर, वहाँ कोई विधि नहीं है। तो, किस तरह का काला जादू हो रहा है? आइए इसे समझें! Route get() get() नियमित अग्रभाग कृपया ध्यान दें कि मैंने अधिकांश PHPDocs को हटा दिया है और सरलता के लिए प्रकारों को इनलाइन कर दिया है, "..." अधिक कोड को संदर्भित करता है। मैं दृढ़ता से सुझाव देता हूं कि किसी भी भ्रम से बचने के लिए आप अपना आईडीई खोलें और कोड का अनुसरण करें। हमारे उदाहरण का अनुसरण करते हुए, आइए वर्ग का अन्वेषण करें। Route <?php namespace Illuminate\Support\Facades; class Route extends Facade { // ... protected static function getFacadeAccessor(): string { return 'router'; } } यहाँ बहुत कुछ नहीं है, बस विधि है जो स्ट्रिंग लौटाती है। इसे ध्यान में रखते हुए, चलिए पैरेंट क्लास पर चलते हैं। getFacadeAccessor() router <?php namespace Illuminate\Support\Facades; use RuntimeException; // ... abstract class Facade { // ... public static function __callStatic(string $method, array $args): mixed { $instance = static::getFacadeRoot(); if (! $instance) { throw new RuntimeException('A facade root has not been set.'); } return $instance->$method(...$args); } } पैरेंट क्लास के अंदर, बहुत सारे तरीके हैं, हालांकि तरीका नहीं है। लेकिन एक दिलचस्प तरीका है, तरीका। यह एक तरीका है, जिसे तब भी बुलाया जाता है जब कोई अपरिभाषित स्थिर तरीका, जैसे कि हमारे मामले में , बुलाया जाता है। इसलिए, हमारा कॉल दर्शाता है कि को बुलाते समय हमने क्या पास किया, रूट और एक जो स्वागत दृश्य लौटाता है। get() __callStatic() जादुई get() __callStatic('get', ['/', Closure()]) Route::get() / Closure() जब ट्रिगर होता है, तो यह सबसे पहले को कॉल करके एक वेरिएबल सेट करने का प्रयास करता है, उस वास्तविक क्लास को रखता है जिस पर कॉल को अग्रेषित किया जाना चाहिए, आइए इसे करीब से देखें, यह थोड़ी देर में समझ में आ जाएगा __callStatic() getFacadeRoot() $instance $instance // Facade.php public static function getFacadeRoot() { return static::resolveFacadeInstance(static::getFacadeAccessor()); } अरे, देखो यह चाइल्ड क्लास से है, जिसे हम जानते हैं कि स्ट्रिंग लौटाता है। यह स्ट्रिंग फिर को पास की जाती है, जो इसे एक क्लास में हल करने का प्रयास करती है, एक तरह की मैपिंग जो कहती है "यह स्ट्रिंग किस क्लास का प्रतिनिधित्व करती है?" आइए देखें। Route getFacadeAccessor() router router resolveFacadeInstance() // Facade.php protected static function resolveFacadeInstance($name) { if (isset(static::$resolvedInstance[$name])) { return static::$resolvedInstance[$name]; } if (static::$app) { if (static::$cached) { return static::$resolvedInstance[$name] = static::$app[$name]; } return static::$app[$name]; } } यह सबसे पहले जाँचता है कि क्या स्टैटिक ऐरे, , में दिए गए (जो, फिर से, है) के साथ कोई मान सेट है। यदि यह कोई मिलान पाता है, तो यह केवल उस मान को लौटाता है। यह प्रदर्शन को थोड़ा अनुकूलित करने के लिए Laravel कैशिंग है। यह कैशिंग एक ही अनुरोध के भीतर होती है। यदि इस विधि को एक ही अनुरोध के भीतर एक ही तर्क के साथ कई बार कॉल किया जाता है, तो यह कैश किए गए मान का उपयोग करता है। आइए मान लें कि यह प्रारंभिक कॉल है और आगे बढ़ें। $resolvedInstance $name router इसके बाद यह जाँचता है कि क्या सेट है, और एप्लीकेशन कंटेनर का एक उदाहरण है $app $app // Facade.php protected static \Illuminate\Contracts\Foundation\Application $app; अगर आप इस बारे में उत्सुक हैं कि एप्लीकेशन कंटेनर क्या है, तो इसे एक बॉक्स के रूप में सोचें जहाँ आपकी क्लासेस स्टोर की जाती हैं। जब आपको उन क्लासेस की ज़रूरत होती है, तो आप बस उस बॉक्स में पहुँच जाते हैं। कभी-कभी, यह कंटेनर थोड़ा जादू करता है। भले ही बॉक्स खाली हो, और आप क्लास लेने के लिए पहुँचते हैं, यह आपके लिए उसे ले आएगा। यह किसी दूसरे लेख का विषय है। अब, आप सोच रहे होंगे, " कब सेट किया जाता है?", क्योंकि इसे सेट किया जाना चाहिए, अन्यथा, हमारे पास नहीं होगा। यह एप्लिकेशन कंटेनर हमारे एप्लिकेशन की बूटस्ट्रैपिंग प्रक्रिया के दौरान सेट हो जाता है। आइए क्लास पर एक त्वरित नज़र डालें: $app $instance \Illuminate\Foundation\Http\Kernel <?php namespace Illuminate\Foundation\Http; use Illuminate\Http\Request; use Illuminate\Http\Response; use Illuminate\Support\Facades\Facade; use Illuminate\Contracts\Http\Kernel as KernelContract; // ... class Kernel implements KernelContract { // ... protected $app; protected $bootstrappers = [ \Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables::class, \Illuminate\Foundation\Bootstrap\LoadConfiguration::class, \Illuminate\Foundation\Bootstrap\HandleExceptions::class, \Illuminate\Foundation\Bootstrap\RegisterFacades::class, // <- this guy \Illuminate\Foundation\Bootstrap\RegisterProviders::class, \Illuminate\Foundation\Bootstrap\BootProviders::class, ]; public function bootstrap(): void { if (! $this->app->hasBeenBootstrapped()) { $this->app->bootstrapWith($this->bootstrappers()); } } } जब कोई अनुरोध आता है, तो उसे राउटर को भेजा जाता है। उसके ठीक पहले, विधि को लागू किया जाता है, जो एप्लिकेशन तैयार करने के लिए सरणी का उपयोग करता है। यदि आप क्लास में विधि का पता लगाते हैं, तो यह इन बूटस्ट्रैपर्स के माध्यम से पुनरावृति करता है, उनकी विधि को कॉल करता है। bootstrap() bootstrappers \Illuminate\Foundation\Application bootstrapWith() bootstrap() सरलता के लिए, आइए हम केवल पर ध्यान केंद्रित करें, जिसके बारे में हम जानते हैं कि इसमें विधि शामिल है जिसे में लागू किया जाएगा \Illuminate\Foundation\Bootstrap\RegisterFacades bootstrap() bootstrapWith() <?php namespace Illuminate\Foundation\Bootstrap; use Illuminate\Contracts\Foundation\Application; use Illuminate\Foundation\AliasLoader; use Illuminate\Foundation\PackageManifest; use Illuminate\Support\Facades\Facade; class RegisterFacades { // ... public function bootstrap(Application $app): void { Facade::clearResolvedInstances(); Facade::setFacadeApplication($app); // Interested here AliasLoader::getInstance(array_merge( $app->make('config')->get('app.aliases', []), $app->make(PackageManifest::class)->aliases() ))->register(); } } और बस, हम स्टैटिक विधि का उपयोग करके क्लास पर एप्लिकेशन कंटेनर सेट कर रहे हैं। setFacadeApplication(). Facade // RegisterFacades.php public static function setFacadeApplication($app) { static::$app = $app; } देखिए, हम प्रॉपर्टी असाइन करते हैं जिसका परीक्षण हम के भीतर कर रहे हैं। इससे प्रश्न का उत्तर मिल जाता है; चलिए आगे बढ़ते हैं। $app resolveFacadeInstance() // Facade.php protected static function resolveFacadeInstance($name) { if (isset(static::$resolvedInstance[$name])) { return static::$resolvedInstance[$name]; } if (static::$app) { if (static::$cached) { return static::$resolvedInstance[$name] = static::$app[$name]; } return static::$app[$name]; } } हमने पुष्टि की है कि एप्लिकेशन बूटस्ट्रैपिंग के दौरान सेट किया गया है। अगला चरण यह जांचना है कि हल किए गए इंस्टेंस को सत्यापित करके कैश किया जाना चाहिए या नहीं, जो डिफ़ॉल्ट रूप से true होता है। अंत में, हम एप्लिकेशन कंटेनर से इंस्टेंस को पुनः प्राप्त करते हैं, हमारे मामले में, यह स्ट्रिंग से बंधी कोई भी क्लास प्रदान करने के लिए कहने जैसा है। $app $cached static::$app['router'] router अब, आप सोच रहे होंगे कि हम एक ऐरे की तरह क्यों एक्सेस करते हैं, जबकि यह एप्लीकेशन कंटेनर का एक इंस्टेंस है, यानी एक । खैर, आप सही कह रहे हैं! हालाँकि, एप्लीकेशन कंटेनर नामक एक PHP इंटरफ़ेस को लागू करता है, जो ऐरे जैसी पहुँच की अनुमति देता है। हम इस तथ्य की पुष्टि करने के लिए इस पर एक नज़र डाल सकते हैं: $app ऑब्जेक्ट ArrayAccess <?php namespace Illuminate\Container; use ArrayAccess; // <- this guy use Illuminate\Contracts\Container\Container as ContainerContract; class Container implements ArrayAccess, ContainerContract { // ... } तो, वास्तव में स्ट्रिंग से बंधा एक इंस्टेंस लौटाता है, विशेष रूप से, । मुझे कैसे पता चला? फ़ेसेड पर एक नज़र डालें; अक्सर, आपको एक PHPDoc मिलेगा जो इस फ़ेसेड के बारे में संकेत देता है कि यह फ़ेसेड क्या छुपाता है या, अधिक सटीक रूप से, हमारे विधि कॉल किस क्लास के लिए प्रॉक्सी होंगे। resolveFacadeInstance() router \Illuminate\Routing\Router Route @see अब, विधि पर वापस आते हैं। __callStatic <?php namespace Illuminate\Support\Facades; use RuntimeException; // ... abstract class Facade { // ... public static function __callStatic(string $method, array $args): mixed { $instance = static::getFacadeRoot(); if (! $instance) { throw new RuntimeException('A facade root has not been set.'); } return $instance->$method(...$args); } } हमारे पास है, क्लास का एक ऑब्जेक्ट है। हम जाँचते हैं कि क्या यह सेट है (जो, हमारे मामले में, पुष्टि की गई है), और हम सीधे इस पर विधि को लागू करते हैं। तो, हम अंत में पाते हैं। $instance \Illuminate\Routing\Router // Facade.php return $instance->get('/', Closure()); और अब, आप पुष्टि कर सकते हैं कि वर्ग में मौजूद है। get() \Illuminate\Routing\Router <?php namespace Illuminate\Routing; use Illuminate\Routing\Route; use Illuminate\Contracts\Routing\BindingRegistrar; use Illuminate\Contracts\Routing\Registrar as RegistrarContract; // ... class Router implements BindingRegistrar, RegistrarContract { // ... public function get(string $uri, array|string|callable|null $action = null): Route { return $this->addRoute(['GET', 'HEAD'], $uri, $action); } } बस इतना ही! क्या अंत में यह मुश्किल नहीं था? संक्षेप में, एक फ़ेसेड एक स्ट्रिंग लौटाता है जो कंटेनर से बंधा होता है। उदाहरण के लिए, क्लास से बंधा हो सकता है। जब हम फ़ेसेड पर एक अपरिभाषित विधि को स्थिर रूप से लागू करते हैं, उदाहरण के लिए , कदम बढ़ाता है। hello-world HelloWorld HelloWorldFacade __callStatic() यह अपने विधि में पंजीकृत स्ट्रिंग को कंटेनर के भीतर जो भी बाउंड है, उसे हल करता है और उस पुनर्प्राप्त इंस्टेंस के लिए हमारी कॉल को प्रॉक्सी करता है। इस प्रकार, हम के साथ समाप्त होते हैं। यही इसका सार है! अभी भी आपके लिए क्लिक नहीं किया? तो चलिए अपना मुखौटा बनाते हैं! getFacadeAccessor() (new HelloWorld())->method() चलो अपना मुखौटा बनाते हैं मान लीजिए हमारे पास यह वर्ग है: <?php namespace App\Http\Controllers; class HelloWorld { public function greet(): string { return "Hello, World!"; } } लक्ष्य लागू करना है। ऐसा करने के लिए, हम अपने क्लास को एप्लिकेशन कंटेनर से जोड़ेंगे। सबसे पहले, पर जाएँ। HelloWorld::greet() AppServiceProvider <?php namespace App\Providers; use App\Http\Controllers; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { public function register(): void { $this->app->bind('hello-world', function ($app) { return new HelloWorld; }); } // ... } अब, जब भी हम अपने एप्लिकेशन कंटेनर (या बॉक्स, जैसा कि मैंने पहले उल्लेख किया है) से अनुरोध करते हैं, तो यह का एक उदाहरण लौटाता है। क्या बचा है? बस एक मुखौटा बनाएँ जो स्ट्रिंग लौटाता है। hello-world HelloWorld hello-world <?php namespace App\Http\Facades; use Illuminate\Support\Facades\Facade; class HelloWorldFacade extends Facade { protected static function getFacadeAccessor() { return 'hello-world'; } } यह सब होने के बाद, हम इसका उपयोग करने के लिए तैयार हैं। चलिए इसे अपने web.php. <?php use App\Http\Facades; use Illuminate\Support\Facades\Route; Route::get('/', function () { return HelloWorldFacade::greet(); // Hello, World! }); हम जानते हैं कि मुखौटे पर मौजूद नहीं है, ट्रिगर होता है। यह एप्लिकेशन कंटेनर से एक स्ट्रिंग (हमारे मामले में ) द्वारा दर्शाए गए क्लास को खींचता है। और हमने में यह बाइंडिंग पहले ही बना ली है; हमने इसे का एक इंस्टेंस प्रदान करने का निर्देश दिया है जब भी कोई अनुरोध करता है। नतीजतन, कोई भी कॉल, जैसे कि , के उस पुनर्प्राप्त इंस्टेंस पर काम करेगा। और बस। HelloWorldFacade greet() __callStatic() hello-world AppServiceProvider HelloWorld hello-world greet() HelloWorld बधाई हो! आपने अपना खुद का मुखौटा बना लिया है! लारवेल रियल-टाइम फ़ेसेड्स अब जब आपको फ़ेसेड की अच्छी समझ हो गई है, तो एक और जादुई ट्रिक का खुलासा करना बाकी है। कल्पना करें कि आप फ़ेसेड बनाए बिना, उपयोग करके को कॉल कर पाएँ। रियल-टाइम फ़ेसेड का HelloWorld::greet() चलो देखते हैं: <?php use Facades\App\Http\Controllers; // Notice the prefix use Illuminate\Support\Facades\Route; Route::get('/', function () { return HelloWorld::greet(); // Hello, World! }); नियंत्रक के नामस्थान में उपसर्ग लगाकर, हम पहले जैसा ही परिणाम प्राप्त करते हैं। लेकिन, यह निश्चित है कि नियंत्रक में नामक कोई स्थिर विधि नहीं है! और आखिर कहाँ से आता है? मैं समझता हूँ कि यह कुछ जादू की तरह लग सकता है, लेकिन एक बार जब आप इसे समझ लेते हैं, तो यह काफी सरल है। Facades HelloWorld greet() Facades\App\Http\Controllers\HelloWorld आइए हम पर करीब से नज़र डालें, जिसकी हमने पहले जाँच की थी, यह \Illuminate\Foundation\Bootstrap\RegisterFacades $app: <?php namespace Illuminate\Foundation\Bootstrap; use Illuminate\Contracts\Foundation\Application; use Illuminate\Foundation\AliasLoader; use Illuminate\Foundation\PackageManifest; use Illuminate\Support\Facades\Facade; class RegisterFacades { public function bootstrap(Application $app): void { Facade::clearResolvedInstances(); Facade::setFacadeApplication($app); AliasLoader::getInstance(array_merge( $app->make('config')->get('app.aliases', []), $app->make(PackageManifest::class)->aliases() ))->register(); // Interested here } } आप अंत में देख सकते हैं कि विधि लागू की गई है। आइए अंदर झांकें: register() <?php namespace Illuminate\Foundation; class AliasLoader { // ... protected $registered = false; public function register(): void { if (! $this->registered) { $this->prependToLoaderStack(); $this->registered = true; } } } वैरिएबल को शुरू में पर सेट किया जाता है। इसलिए, हम स्टेटमेंट दर्ज करते हैं और विधि को कॉल करते हैं। अब, आइए इसके कार्यान्वयन का पता लगाते हैं। $registered false if prependToLoaderStack() // AliasLoader.php protected function prependToLoaderStack(): void { spl_autoload_register([$this, 'load'], true, true); } यहीं पर जादू होता है! Laravel फ़ंक्शन को कॉल कर रहा है, जो एक अंतर्निहित PHP फ़ंक्शन है जो किसी अपरिभाषित क्लास तक पहुँचने का प्रयास करते समय ट्रिगर होता है। यह ऐसी स्थितियों में निष्पादित करने के लिए तर्क को परिभाषित करता है। इस मामले में, Laravel अपरिभाषित कॉल का सामना करने पर विधि को लागू करना चुनता है। spl_autoload_register() load() इसके अतिरिक्त, स्वचालित रूप से अपरिभाषित वर्ग का नाम उस विधि या फ़ंक्शन को भेज देता है जिसे वह कॉल करता है। spl_autoload_register() आइए विधि का अन्वेषण करें; यह कुंजी होनी चाहिए। load() // AliasLoader.php public function load($alias) { if (static::$facadeNamespace && str_starts_with($alias, static::$facadeNamespace)) { $this->loadFacade($alias); return true; } if (isset($this->aliases[$alias])) { return class_alias($this->aliases[$alias], $alias); } } हम जाँचते हैं कि क्या सेट है, और यदि जो भी क्लास पास हुई है, हमारे मामले में, में जो भी सेट है, उसके साथ शुरू होती है $facadeNamespace Facades\App\Http\Controllers\HelloWorld $facadeNamespace तर्क यह जाँचता है कि क्या सेट है और क्या पारित वर्ग, हमारे मामले में (जो अपरिभाषित है), $facadeNamespace Facades\App\Http\Controllers\HelloWorld $facadeNamespace. // AliasLoader.php protected static $facadeNamespace = 'Facades\\'; चूँकि हमने अपने कंट्रोलर के नामस्थान के आगे लगा दिया है, जो शर्त को पूरा करता है, इसलिए हम पर आगे बढ़ते हैं Facades loadFacade() // AliasLoader.php protected function loadFacade($alias) { require $this->ensureFacadeExists($alias); } यहाँ, विधि को से लौटाए गए पथ की आवश्यकता होती है। इसलिए, अगला चरण इसके कार्यान्वयन में गहराई से जाना है। ensureFacadeExists() // AliasLoader.php protected function ensureFacadeExists($alias) { if (is_file($path = storage_path('framework/cache/facade-'.sha1($alias).'.php'))) { return $path; } file_put_contents($path, $this->formatFacadeStub( $alias, file_get_contents(__DIR__.'/stubs/facade.stub') )); return $path; } सबसे पहले, यह पता लगाने के लिए जाँच की जाती है कि नाम की कोई फ़ाइल मौजूद है या नहीं। हमारे मामले में, यह फ़ाइल मौजूद नहीं है, जो अगले चरण को ट्रिगर करती है: । यह फ़ंक्शन एक फ़ाइल बनाता है और उसे निर्दिष्ट पर सहेजता है। फ़ाइल की सामग्री द्वारा उत्पन्न की जाती है, जो, इसके नाम से देखते हुए, एक स्टब से एक मुखौटा बनाता है। यदि आप निरीक्षण करते हैं, तो आपको निम्नलिखित मिलेगा: framework/cache/facade-'.sha1($alias).'.php' file_put_contents() $path formatFacadeStub() facade.stub <?php namespace DummyNamespace; use Illuminate\Support\Facades\Facade; /** * @see \DummyTarget */ class DummyClass extends Facade { /** * Get the registered name of the component. */ protected static function getFacadeAccessor(): string { return 'DummyTarget'; } } परिचित लग रहा है? हमने मूल रूप से यही मैन्युअली किया था। अब, उपसर्ग को हटाने के बाद डमी सामग्री को हमारे अपरिभाषित वर्ग से बदल देता है। यह अपडेट किया गया मुखौटा तब संग्रहीत किया जाता है। परिणामस्वरूप, जब फ़ाइल की आवश्यकता होती है, तो यह सही तरीके से करता है, और इसे निम्न फ़ाइल की आवश्यकता होती है: formatFacadeStub() Facades\\ loadFacade() <?php namespace Facades\App\Http\Controllers; use Illuminate\Support\Facades\Facade; /** * @see \App\Http\Controllers\HelloWorld */ class HelloWorld extends Facade { /** * Get the registered name of the component. */ protected static function getFacadeAccessor(): string { return 'App\Http\Controllers\HelloWorld'; } } और अब, सामान्य प्रवाह में, हम एप्लिकेशन कंटेनर स्ट्रिंग से बंधे किसी भी इंस्टेंस को वापस करने के लिए कहते हैं। आप सोच रहे होंगे कि हमने इस स्ट्रिंग को किसी भी चीज़ से नहीं बांधा, हमने अपने भी नहीं छुआ। लेकिन याद रखें कि मैंने शुरुआत में एप्लिकेशन कंटेनर के बारे में क्या बताया था? App\Http\Controllers\HelloWorld AppServiceProvider , लेकिन एक शर्त के साथ, क्लास में कंस्ट्रक्टर नहीं होना चाहिए। अन्यथा, यह नहीं जानता कि इसे आपके लिए कैसे बनाया जाए। हमारे मामले में, हमारे क्लास को निर्माण के लिए किसी तर्क की आवश्यकता नहीं है। इसलिए, कंटेनर इसे हल करता है, इसे लौटाता है और सभी कॉल इसके लिए प्रॉक्सी हो जाती हैं। भले ही बॉक्स खाली हो, यह इंस्टेंस लौटाएगा HelloWorld रीयल-टाइम फ़ेसेड को फिर से समझना: हमने अपने क्लास के आगे लगा दिया है। एप्लिकेशन बूटस्ट्रैपिंग के दौरान, Laravel रजिस्टर करता है, जो तब ट्रिगर होता है जब हम अपरिभाषित क्लास को कॉल करते हैं। यह अंततः विधि की ओर ले जाता है। अंदर, हम जाँचते हैं कि क्या मौजूदा अपरिभाषित क्लास के आगे लगा है। यह मेल खाता है, इसलिए Laravel इसे लोड करने की कोशिश करता है। Facades spl_autoload_register() load() load() Facades चूँकि मुखौटा मौजूद नहीं है, इसलिए यह इसे स्टब से बनाता है और फिर फ़ाइल की आवश्यकता होती है। और वाह! आपके पास एक नियमित मुखौटा है, लेकिन यह एक को तुरंत बनाया गया था। बहुत बढ़िया, है न? निष्कर्ष यहाँ तक पहुँचने के लिए बधाई! मैं समझता हूँ कि यह थोड़ा भारी हो सकता है। बेझिझक वापस जाएँ और उन अनुभागों को फिर से पढ़ें जो आपके लिए ठीक से क्लिक नहीं हुए। अपने IDE के साथ अनुवर्ती कार्रवाई भी मदद कर सकती है। लेकिन अरे, अब कोई काला जादू नहीं, अच्छा लग रहा होगा, कम से कम मुझे पहली बार ऐसा ही लगा! और याद रखें, अगली बार जब आप किसी विधि को स्टेटिकली कॉल करेंगे, तो हो सकता है कि ऐसा न हो 🪄