PHP Legacy कोड रिफैक्टरिंग: शुरू से अंत तक
\n\nपुराने (legacy) PHP कोड के साथ काम करना कई डेवलपर्स के लिए एक अपरिहार्य वास्तविकता है। 5-10 साल पहले लिखे गए प्रोजेक्ट्स में अक्सर "स्पेगेटी कोड" होता है - ग्लोबल वेरिएबल्स, बिज़नेस लॉजिक और प्रेजेंटेशन का मिश्रण, टाइपिंग की कमी, और पुराने फंक्शन (mysql_*, ereg आदि)। इस लेख में हम PHP legacy कोड को रिफैक्टर करने की चरण-दर-चरण रणनीति समझेंगे, जिससे प्रोजेक्ट को बिना रोके बेहतर बनाया जा सके।
\n\nLegacy कोड रिफैक्टरिंग क्यों मुश्किल है?
\n\nLegacy कोड की सबसे बड़ी समस्या है टेस्ट का न होना। आप निश्चित नहीं हो सकते कि बदलाव मौजूदा फंक्शनैलिटी को नहीं तोड़ेंगे। अतिरिक्त चुनौतियाँ:
\n\n- \n
- डॉक्यूमेंटेशन का अभाव — काम करने का तर्क अक्सर समझ से परे होता है \n
- लेयर्स का मिश्रण — HTML टेम्पलेट्स के अंदर SQL क्वेरीज़ \n
- ग्लोबल स्टेट — वेरिएबल्स जो कोड के किसी भी हिस्से से एक्सेस किए जा सकते हैं \n
- पुराने पैटर्न — register_globals, mysql_* फंक्शन का उपयोग \n
- कठोर निर्भरताएँ — क्लासेस के अंदर सीधे
newके ज़रिए ऑब्जेक्ट बनाना \n
रिफैक्टरिंग की तैयारी: "सुरक्षा जाल" बनाना
\n\nकोड बदलने से पहले, यह सुनिश्चित करना ज़रूरी है कि आप त्रुटियाँ पकड़ सकें। ये अनिवार्य कदम हैं:
\n\n1. कैरेक्टराइज़ेशन टेस्ट जोड़ना
\n\nकैरेक्टराइज़ेशन टेस्ट कोड के मौजूदा व्यवहार को रिकॉर्ड करते हैं। ये कोड लिखे जाने के बाद बनाए जाते हैं और यह सुनिश्चित करते हैं कि रिफैक्टरिंग से व्यवहार नहीं बदला।
\n\n<?php\n// Legacy फंक्शन के लिए कैरेक्टराइज़ेशन टेस्ट का उदाहरण\nclass LegacyCalculatorTest extends PHPUnit\\Framework\\TestCase\n{\n public function testCalculateTotal()\n {\n // मौजूदा व्यवहार को रिकॉर्ड करें\n $result = legacy_calculate_total(100, 0.2);\n $this->assertEquals(120, $result);\n }\n}\n\n\n2. टेस्ट का "कंबल" बनाना
\n\nइंटीग्रेशन टेस्ट से शुरू करें जो मुख्य यूज़र सीनारियो (रजिस्ट्रेशन, ऑर्डर प्लेसमेंट आदि) की जाँच करते हैं। इससे रिफैक्टरिंग के दौरान बुनियादी विश्वास मिलेगा।
\n\nPHP Legacy कोड रिफैक्टरिंग की चरण-दर-चरण रणनीति
\n\n"Strangler Fig Pattern" (उदासीन अंजीर) दृष्टिकोण का उपयोग करें — सिस्टम को रोके बिना पुराने कंपोनेंट्स को धीरे-धीरे नए से बदलें।
\n\nचरण 1: ग्लोबल स्टेट को अलग और एनकैप्सुलेट करें
\n\nग्लोबल वेरिएबल्स और फंक्शन रिफैक्टरिंग के सबसे बड़े दुश्मन हैं। उन्हें एनकैप्सुलेट करके शुरू करें:
\n\n<?php\n// पहले: ग्लोबल फंक्शन और वेरिएबल\n$db = mysql_connect('localhost', 'user', 'pass');\nfunction get_user($id) {\n global $db;\n $result = mysql_query("SELECT * FROM users WHERE id = $id", $db);\n return mysql_fetch_assoc($result);\n}\n\n// बाद में: स्पष्ट निर्भरता वाली क्लास\nclass UserRepository {\n private PDO $pdo;\n \n public function __construct(PDO $pdo) {\n $this->pdo = $pdo;\n }\n \n public function findById(int $id): ?array {\n $stmt = $this->pdo->prepare('SELECT * FROM users WHERE id = ?');\n $stmt->execute([$id]);\n $user = $stmt->fetch();\n return $user ?: null;\n }\n}\n\n\nचरण 2: लॉजिक को प्रेजेंटेशन से अलग करें
\n\nसामान्य legacy कोड में SQL और PHP लॉजिक सीधे HTML में होता है। अलग करने के लिए "टेम्पलेट मेथड" पैटर्न का उपयोग करें:
\n\n<?php\n// पहले: टेम्पलेट में स्पेगेटी कोड\n?>\n<ul>\n<?php\n$result = mysql_query("SELECT * FROM products");\nwhile ($row = mysql_fetch_assoc($result)) {\n echo "<li>" . $row['name'] . " - " . $row['price'] . " रु.</li>";\n}\n?>\n</ul>\n\n// बाद में: लॉजिक को सर्विस में अलग करना\nclass ProductService {\n public function __construct(private ProductRepository $repo) {}\n \n public function getProductList(): array {\n return $this->repo->findAll();\n }\n}\n\n// टेम्पलेट में