एक गलती का इतिहास: mysql_* क्यों पुरानी बात है
\n\nकल्पना करें: आप PHP में एक वेबसाइट लिख रहे हैं, MySQL डेटाबेस से कनेक्ट हो रहे हैं और विश्वविद्यालय से परिचित फ़ंक्शन mysql_query() का उपयोग कर रहे हैं। सब कुछ काम करता है, साइट चलती है, उपयोगकर्ता संतुष्ट हैं। लेकिन एक दिन आप लॉग में एक अजीब चेतावनी देखते हैं: «Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future»। यह सिर्फ इंटरप्रेटर की डांट नहीं है - यह एक लाल झंडा है जिसे नजरअंदाज नहीं किया जा सकता।
Stack Overflow पर प्रश्न «Why shouldn't I use mysql_* functions in PHP?» ने हजारों व्यूज और सैकड़ों टिप्पणियां एकत्र की हैं। और यह आकस्मिक नहीं है। इस लेख में हम समझेंगे कि mysql_* फ़ंक्शन (mysql_connect, mysql_query, mysql_fetch_array और अन्य) PHP डेवलपर्स के लिए नंबर एक दुश्मन क्यों बन गए, वास्तविक कोड उदाहरणों के साथ दिखाएंगे कि उन्हें किससे बदलना है, और माइग्रेशन के लिए एक चरण-दर-चरण योजना देंगे।
\n\nmysql_* क्या है और उन्हें क्यों हटाया गया?
\n\nmysql_* एक्सटेंशन (मूल MySQL) PHP 2.0 में 1997 में दूर के अतीत में दिखाई दिया। यह सरल और सहज था: mysql_connect() कॉल किया, mysql_query() के माध्यम से क्वेरी निष्पादित की, परिणाम प्राप्त किया। लेकिन इस सादगी का एक अंधकारमय पक्ष था।
PHP 5.5.0 से शुरू होकर, सभी mysql_* फ़ंक्शन को पुराना (deprecated) घोषित किया गया, और PHP 7.0 में उन्हें पूरी तरह से हटा दिया गया। यदि आप PHP 7+ पर mysql_connect() का उपयोग करने का प्रयास करते हैं, तो आपको एक घातक त्रुटि मिलेगी: Call to undefined function mysql_connect()। इसका कारण PHP डेवलपर्स की सनक नहीं, बल्कि सुरक्षा और आर्किटेक्चर की मूलभूत समस्याएं हैं।
mysql_* को छोड़ने के तीन मुख्य कारण
\n\n- \n
- बिना सुरक्षा के SQL-इंजेक्शन — फ़ंक्शन तैयार क्वेरी (prepared statements) का समर्थन नहीं करते, जिससे मैन्युअल एस्केपिंग अनिवार्य हो जाती है, लेकिन अक्सर भूला दिया जाता है। \n
- पुरानी आर्किटेक्चर — ऑब्जेक्ट-ओरिएंटेड शैली, स्टोर्ड प्रोसीजर, मल्टीपल क्वेरी और ट्रांजेक्शन का कोई समर्थन नहीं है। \n
- विकास का अभाव — एक्सटेंशन वर्षों से अपडेट नहीं किया गया, जबकि MySQL बदलता रहा (उदाहरण के लिए, नए डेटा प्रकार, एन्कोडिंग, प्रमाणीकरण तंत्र सामने आए)। \n
जीवंत उदाहरण: कैसे mysql_* आपकी साइट को मारता है
\n\nआइए क्लासिक कोड देखें जो अभी भी पुरानी पाठ्यपुस्तकों और फ़ोरम में पाया जाता है:
\n\n<?php\n// पुराना कोड - उपयोग न करें!\n$link = mysql_connect('localhost', 'root', 'password');\nmysql_select_db('users_db', $link);\n\n$user_input = $_GET['username']; // उपयोगकर्ता इनपुट करता है: ' OR 1=1 --\n$query = "SELECT * FROM users WHERE username = '$user_input'";\n$result = mysql_query($query, $link);\n\nwhile ($row = mysql_fetch_assoc($result)) {\n echo "नमस्ते, " . $row['username'] . "<br>";\n}\n?>\n\nसमस्या क्या है? यदि कोई हमलावर पैरामीटर username में मान ' OR 1=1 -- भेजता है, तो क्वेरी बन जाती है:
SELECT * FROM users WHERE username = '' OR 1=1 --\n\nडबल डैश -- क्वेरी के बाकी हिस्से को कमेंट कर देगा, और शर्त 1=1 हमेशा सत्य होती है। परिणामस्वरूप, आपको डेटाबेस के सभी उपयोगकर्ता मिलेंगे, जिनमें पासवर्ड, ईमेल और अन्य गोपनीय जानकारी शामिल है। यह सिद्धांत नहीं है - यह एक वास्तविक कमजोरी है जो हर दिन हजारों साइटों को तोड़ती है।
बेशक, आप mysql_real_escape_string() का उपयोग कर सकते हैं, लेकिन:
- \n
- डेवलपर्स अक्सर इसे कॉल करना भूल जाते हैं। \n
- यह सभी प्रकार के हमलों से नहीं बचाता (उदाहरण के लिए, एन्कोडिंग का उपयोग करके हमलों से)। \n
- कोड गंदा और पढ़ने में मुश्किल हो जाता है। \n
mysql_* को किससे बदलें: दो आधुनिक दृष्टिकोण
\n\nआधुनिक PHP में MySQL के साथ काम करने के लिए दो योग्य एक्सटेंशन हैं: mysqli (MySQL Improved) और PDO (PHP Data Objects)। दोनों समर्थन करते हैं