PHP में Dependency Injection (DI) का परिचय
PHP में आधुनिक विकास घटकों के कमजोर युग्मन के सिद्धांतों को समझे बिना संभव नहीं है। Dependency Injection (DI), या निर्भरता इंजेक्शन, प्रमुख डिज़ाइन पैटर्न में से एक है जो लचीले, परीक्षण योग्य और आसानी से रखरखाव योग्य एप्लिकेशन बनाने की अनुमति देता है। क्लास द्वारा स्वयं अपनी निर्भरताएँ (जैसे डेटाबेस ऑब्जेक्ट या लॉगर) बनाने के बजाय, वह उन्हें बाहर से प्राप्त करता है। यह कोड की आर्किटेक्चर को मौलिक रूप से बदल देता है।
इस लेख में, हम विस्तार से समझेंगे कि PHP में Dependency Injection क्या है, इंजेक्शन के कौन से तरीके मौजूद हैं, DI-कंटेनर कैसे काम करता है और यह पैटर्न Laravel, Symfony और Yii2 जैसे आधुनिक फ्रेमवर्क के लिए मानक क्यों बन गया है।
1. समस्या: कठोर युग्मन (Tight Coupling)
समाधान के बारे में बात करने से पहले, आइए समस्या पर नज़र डालें। एक क्लासिक उदाहरण — क्लास UserController, जो सीधे अपने अंदर Database ऑब्जेक्ट बनाता है:
<?phpclass Database { public function query(string $sql): array { // डेटाबेस से कनेक्शन और क्वेरी निष्पादन return []; }}
class UserController { private Database $db;
public function __construct() { // कठोर निर्भरता — कंस्ट्रक्टर के अंदर ऑब्जेक्ट बनाते हैं $this->db = new Database(); }
public function getUsers(): array { return $this->db->query('SELECT * FROM users'); }}?>इस दृष्टिकोण के नुकसान:
- परीक्षण में कठिनाई: आप यूनिट टेस्ट में
Databaseको mock-ऑब्जेक्ट से प्रतिस्थापित नहीं कर सकते। - एकल जिम्मेदारी सिद्धांत (SRP) का उल्लंघन: क्लास न केवल बिज़नेस लॉजिक के लिए बल्कि निर्भरताएँ बनाने के लिए भी जिम्मेदार है।
- संशोधन में कठिनाई: यदि आप MySQL को PostgreSQL से बदलना चाहते हैं, तो आपको उन सभी क्लासेस में कोड बदलना होगा जहाँ
Databaseबनाया गया है।
2. समाधान: निर्भरता इंजेक्शन (Dependency Injection)
Dependency Injection निर्भरताओं को बाहर से पास करने का सुझाव देता है। इंजेक्शन के तीन मुख्य तरीके हैं: कंस्ट्रक्टर के माध्यम से, सेटर्स के माध्यम से और इंटरफ़ेस (मेथड) के माध्यम से। आइए प्रत्येक पर विचार करें।
2.1. कंस्ट्रक्टर के माध्यम से इंजेक्शन (Constructor Injection)
सबसे सामान्य और अनुशंसित तरीका। निर्भरताएँ ऑब्जेक्ट बनाते समय एक बार पास की जाती हैं और बाद में बदली नहीं जा सकतीं।
<?phpclass UserController { private Database $db;
// निर्भरता बाहर से पास की जाती है public function __construct(Database $db) { $this->db = $db; }
public function getUsers(): array { return $this->db->query('SELECT * FROM users'); }}
// उपयोग:$db = new Database();$controller = new UserController($db);?>लाभ: गारंटी देता है कि निर्भरता हमेशा उपलब्ध है; अनिवार्य निर्भरताओं के लिए आदर्श। नुकसान: यदि क्लास में कई निर्भरताएँ हैं, तो कंस्ट्रक्टर भारी हो जाता है।
2.2. सेटर्स के माध्यम से इंजेक्शन (Setter Injection)
वैकल्पिक निर्भरताओं के लिए उपयुक्त जो ऑब्जेक्ट बनने के बाद सेट की जा सकती हैं।
<?phpclass Logger { public function log(string $message): void { echo $message; }}
class UserController { private ?Logger $logger = null;
public function setLogger(Logger $logger): void { $this->logger = $logger; }
public function getUsers(): array { if ($this->logger) { $this->logger->log('Fetching users...'); } // उपयोगकर्ता प्राप्त करने का लॉजिक return []; }}
// उपयोग:$controller = new UserController();$controller->setLogger(new Logger());?>लाभ: