flawopen.com/PHP में SQL Injection/mysqli बनाम PDO
MySQLi बनाम PDO: सुरक्षित Prepared Statements
Prepared statement SQL निर्देश स्थिर रखता है और input values अलग भेजता है—जैसे लेबल वाले खाने भरना। PDO और MySQLi दोनों यह कर सकते हैं। सुरक्षा सही value binding से आती है, library के नाम से नहीं।
दोनों API में वही query सुरक्षित रूप से तैयार करें
$userId = $_GET['id']; $sql = "SELECT id, email FROM users WHERE id = " . $userId; // Both calls execute the already-built SQL string: $rows = $mysqli->query($sql); $rows = $pdo->query($sql);
// PDO $stmt = $pdo->prepare( "SELECT id, email FROM users WHERE id = :id" ); $stmt->execute(["id" => $userId]); // MySQLi $stmt = $mysqli->prepare( "SELECT id, email FROM users WHERE id = ?" ); $stmt->bind_param("i", $userId); $stmt->execute();
PDO का मुख्य अंतर database portability है
PDO कई database drivers के लिए एक common interface देता है; MySQLi MySQL और MariaDB पर केंद्रित है। PDO अपने आप SQL को portable नहीं बनाता: dialect, driver behavior और features अलग रहते हैं।
Driver के अनुसार PDO :id जैसे named या ? positional placeholders ले सकता है; एक statement में दोनों न मिलाएँ। MySQLi positional ? इस्तेमाल करता है। दोनों values bind करते हैं, table/column names, keywords या sort direction नहीं।
PDO drivers native या emulated prepares इस्तेमाल कर सकते हैं। MySQL में PDO::ATTR_EMULATE_PREPARES उपलब्ध होने पर emulation नियंत्रित करता है; native prepare उपलब्ध न होने या विफल होने पर fallback हो सकता है। Driver documentation मानें। यह setting interpolated SQL को सुरक्षित नहीं बनाती: SQL स्थिर रखें और values bind करें।
दोनों libraries में SQL Injection रोकने के नियम
prepare() का उपयोग करें और हर अविश्वसनीय value bind करें। SQL syntax स्थिर रखें; dynamic identifiers server-side strict map या सीमित query variants से चुनें। Prepared statement row access authorize नहीं करता; जरूरत पर query को authenticated user तक सीमित करें। LIKE में binding SQL syntax injection रोकता है, लेकिन literal search के लिए escape न करने पर % और _ wildcard रहते हैं।
PDO और MySQLi में चुनाव
- ✓कई drivers पर साझा API चाहिए तो PDO चुनें; migration में SQL dialect और driver व्यवहार जाँचें।
- ✓केवल MySQL/MariaDB और MySQL-specific API चाहिए तो MySQLi चुनें।
- ✓दोनों में interpolation, concatenation और dynamic identifiers जाँचें; values bind करें और records अलग से authorize करें।
अक्सर पूछे जाने वाले प्रश्न
नहीं। Query तैयार और values bind होने पर दोनों values सुरक्षित bind करते हैं। Named placeholders पढ़ने में आसान हो सकते हैं; वे identifiers bind नहीं करते और authorization की जगह नहीं लेते।
हमेशा ऐसा नहीं। Driver support और fallback अलग होते हैं। Documentation और app की जरूरतें देखें। किसी भी mode में SQL स्थिर रखें और values parameters में दें।
नहीं। Parameters values के लिए हैं, SQL identifiers या keywords के लिए नहीं। Client choice को server पर सीमित trusted SQL fragments से map करें।
संदर्भ
- PHP Manual — PDO Prepared Statements
- PHP Manual — MySQLi Prepared Statements
- PHP Manual — PDO::setAttribute और emulated prepares
- FlawOpen — PHP में SQL Injection