PDO में IN() के साथ ऐरे पास करना: आसान और सुरक्षित तरीका

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

"क्या मैं IN() कंडीशन में एक ऐरे बाइंड कर सकता हूँ?" — यह सवाल हर दूसरे PHP डेवलपर को परेशान करता है

\n\n

क्या आपने कभी SELECT * FROM users WHERE id IN (?) जैसा क्वेरी लिखा और bindValue() के ज़रिए उसमें ऐरे पास करने की कोशिश की? अगर हाँ, तो आप उस निराशा को जानते हैं जब PDO सिर्फ एक रो लौटाता है, सभी ज़रूरी रो नहीं। या इससे भी बुरा — एरर फेंक देता है।

\n\n

यह सवाल Stack Overflow पर हज़ारों बार देखा जा चुका है, और यह कोई हैरानी की बात नहीं है। लगता है कितना आसान है: ऐरे पास करो, रिजल्ट पाओ। लेकिन PDO (PHP Data Objects) एक सख्त चीज़ है। यह अपने आप ऐरे को IN() के लिए वैल्यू की लिस्ट में नहीं बदल सकता। और यहीं से मज़ा शुरू होता है: डेवलपर टॉप गलतियाँ करते हैं, जिन्हें हम आज समझेंगे। और सबसे ज़रूरी — उनसे बचना सीखेंगे।

\n\n

इस आर्टिकल में हम सिर्फ तैयार समाधान नहीं देंगे। हम गलत कोड से सुरक्षित, तेज़ और सुंदर कोड तक का सफर तय करेंगे। चलिए शुरू करते हैं!

\n\n

गलती नंबर 1: bindValue के ज़रिए सीधे ऐरे पास करना

\n\n

सबसे आम गलती — ऐरे को सीधे bindValue() में डालने की कोशिश करना।

\n\n
// ❌ गलत\n$ids = [1, 2, 3, 5];\n$stmt = $pdo->prepare("SELECT * FROM users WHERE id IN (?)");\n$stmt->bindValue(1, $ids, PDO::PARAM_STR);\n$stmt->execute();\n$users = $stmt->fetchAll();
\n\n

क्या होगा? PHP ऐरे को स्ट्रिंग "Array" में बदल देगा, और क्वेरी बन जाएगी WHERE id IN ("Array")। नतीजा — जीरो रो या एरर, ड्राइवर पर निर्भर करता है। PDO को समझ नहीं आता कि ऐरे को अलग-अलग प्लेसहोल्डर में बाँटना है।

\n\n

ऐसा क्यों होता है? PDO सिर्फ स्केलर वैल्यू (स्ट्रिंग, नंबर, null) की उम्मीद करता है। ऐरे एक कम्पोजिट टाइप है, जो सीधे बाइंडिंग के लिए उपयुक्त नहीं है।

\n\n

समाधान क्या है?

\n

हर ऐरे एलिमेंट के लिए मैन्युअली प्लेसहोल्डर बनाने होंगे। कोई जादू नहीं, सिर्फ कोड।

\n\n
// ✅ सही\n$ids = [1, 2, 3, 5];\n$placeholders = implode(',', array_fill(0, count($ids), '?'));\n$stmt = $pdo->prepare("SELECT * FROM users WHERE id IN ($placeholders)");\n$stmt->execute($ids);\n$users = $stmt->fetchAll();
\n\n

यहाँ हम ?,?,?,? जैसी स्ट्रिंग बनाते हैं और ऐरे को सीधे execute() में पास करते हैं। PDO अपने आप वैल्यू को क्रम से लगा देगा। सरल और सुरक्षित।

\n\n

गलती नंबर 2: डेटा टाइप को नज़रअंदाज़ करना

\n\n

मान लीजिए आप नेम्ड प्लेसहोल्डर का उपयोग कर रहे हैं। और ऐसा करने का लालच होता है:

\n\n
// ❌ गलत\n$ids = [1, 2, 3];\n$placeholders = [];\nforeach ($ids as $i => $id) {\n    $placeholders[] = ":id_$i";\n}\n$sql = "SELECT * FROM users WHERE id IN (" . implode(',', $placeholders) . ")";\n$stmt = $pdo->prepare($sql);\nforeach ($ids as $i => $id) {\n    $stmt->bindValue(":id_$i", $id, PDO::PARAM_INT);\n}\n$stmt->execute();
\n\n

यह सही लगता है। लेकिन एक पेंच है: अगर ऐरे खाली है, तो क्वेरी WHERE id IN () बन जाएगी, जो SQL सिंटैक्स एरर देगी। दूसरी समस्या — अगर ऐरे में स्ट्रिंग हैं और आपने PDO::PARAM_INT दिया, तो PDO उन्हें शून्य में बदल सकता है।

\n\n

समाधान: हमेशा ऐरे को खाली होने की जाँच करें और टाइप को डायनामिक रूप से निर्धारित करें।

\n\n
// ✅ सही\n$ids = [1, 2, 3];\nif (empty($ids)) {\n    return []; // या एक्सेप्शन फेंकें\n}\n$placeholders = [];\nforeach ($ids as $i => $id) {\n    $placeholders[] = ":id_$i";\n}\n$sql = "SELECT * FROM users WHERE id IN (" . implode(',', $placeholders) . ")";\n$stmt = $pdo->prepare($sql);\nforeach ($ids as $i => $id) {\n    $type = is_int($id) ? PDO::PARAM_INT : PDO::PARAM_STR;\n    $stmt->bindValue(":id_$i", $id, $type);\n}\n$stmt->execute();
\n\n

गलती नंबर 3: "मैन्युअल" एस्केपिंग के ज़रिए SQL इंजेक्शन

\n\n

कुछ डेवलपर निराशा में कुछ ऐसा लिखते हैं

ब्लॉग

पुस्तक अनुशंसाएँ