← Back to PHP Course | Chapter 11: Database | Lesson 5 of 21

PHP Prepared Statements

एक prepared statement blanks वाले एक form letter जैसा है जिसे आप बाद में भरते हैं। क्योंकि question और answers अलग रखे जाते हैं, sneaky visitors आपके database को trick नहीं कर सकते।
Syntax
php
$stmt = $pdo->prepare("SELECT * FROM table_name WHERE column = :name");
$stmt->execute(["name" => $value]);

$stmt = $mysqli->prepare("SELECT * FROM table_name WHERE column = ?");
$stmt->bind_param("s", $value);   // s = string, i = integer
$stmt->execute();

Prepared Statements क्या हैं?

एक prepared statement एक SQL query के fixed structure को उसके operate करने वाले variable data से separate करता है, database को पहले query template भेजते हुए और असली values बाद में parameters की तरह, एक combined string बनाने के बजाय।

उदाहरण: What are Prepared Statements?

php
<?php
// Create a new `SQLite3` instance with ':memory:', stored in `$db`
$db = new SQLite3(':memory:');
$db->exec("CREATE TABLE users (id INTEGER, name TEXT)");
// Declare `$stmt`, set to `$db->prepare("INSERT INTO users (id, name) VALUES (:id, :name)")`
$stmt = $db->prepare("INSERT INTO users (id, name) VALUES (:id, :name)");
// Print "Template prepared before any values are sent" to the output
echo "Template prepared before any values are sent";
?>

Parameters Bind करना

क्योंकि database bound parameters को strictly data की तरह treat करता है — कभी executable SQL syntax की तरह नहीं — prepared statements उन values के लिए SQL injection खत्म कर देते हैं जिन्हें वे cover करते हैं, यही वजह है कि उन्हें इसके against standard defense माना जाता है।

उदाहरण: Binding Parameters

php
<?php
// Create a new `SQLite3` instance with ':memory:', stored in `$db`
$db = new SQLite3(':memory:');
$db->exec("CREATE TABLE users (id INTEGER, name TEXT)");
// Declare `$stmt`, set to `$db->prepare("INSERT INTO users (id, name) VALUES (:id, :name)")`
$stmt = $db->prepare("INSERT INTO users (id, name) VALUES (:id, :name)");
$stmt->bindValue(':id', 1, SQLITE3_INTEGER);
$stmt->bindValue(':name', "Robert'); DROP TABLE users;", SQLITE3_TEXT);
$stmt->execute();
// Print "Malicious input treated as plain data, not SQL" to the output
echo "Malicious input treated as plain data, not SQL";
?>

Statements Execute करना

mysqli में, आप placeholders (?) वाला एक statement prepare करते हैं, bind_param() से हर value का type specify करते हुए values bind करते हैं, फिर execute() call करते हैं — PDO से थोड़ा ज़्यादा verbose flow।

उदाहरण: Executing Statements

php
<?php
// mysqli style: $stmt = $conn->prepare("INSERT INTO users (name) VALUES (?)");
// $stmt->bind_param("s", $name); $stmt->execute();
$db = new SQLite3(':memory:');
$db->exec("CREATE TABLE users (name TEXT)");
$stmt = $db->prepare("INSERT INTO users (name) VALUES (?)");
$stmt->bindValue(1, "Alice", SQLITE3_TEXT);
$stmt->execute();
echo "Executed via positional placeholder";
?>

Results को Safely Fetch करना

PDO में, आप named या positional placeholders वाला एक statement prepare करते हैं और values का एक array सीधे execute($values) को pass करते हैं, जो कई developers को mysqli के अलग bind_param() step से ज़्यादा concise लगता है।

उदाहरण: Fetching Results Safely

php
<?php
// Create a new `PDO` instance with 'sqlite::memory:', stored in `$pdo`
$pdo = new PDO('sqlite::memory:');
$pdo->exec("CREATE TABLE users (name TEXT)");
// Declare `$stmt`, set to `$pdo->prepare("INSERT INTO users (name) VALUES (?)")`
$stmt = $pdo->prepare("INSERT INTO users (name) VALUES (?)");
$stmt->execute(["Alice"]);
// Print "PDO lets you pass values directly to execute()" to the output
echo "PDO lets you pass values directly to execute()";
?>

SQL Injection Protection

एक prepared statement को हर बार SQL re-parse किए बिना अलग-अलग bound values के साथ कई बार execute किया जा सकता है, जो same query बार-बार चलाने पर एक meaningful performance win भी है, जैसे एक loop में कई rows insert करना।

उदाहरण: SQL Injection Protection

php
<?php
// Create a new `SQLite3` instance with ':memory:', stored in `$db`
$db = new SQLite3(':memory:');
$db->exec("CREATE TABLE users (name TEXT)");
// Declare `$stmt`, set to `$db->prepare("INSERT INTO users (name) VALUES (:name)")`
$stmt = $db->prepare("INSERT INTO users (name) VALUES (:name)");
// Loop over `["Alice", "Bob", "Carol"]`, binding each item to `$name`
foreach (["Alice", "Bob", "Carol"] as $name) {
    $stmt->bindValue(':name', $name, SQLITE3_TEXT);
    $stmt->execute();
}
// Print "Same prepared statement reused for each insert" to the output
echo "Same prepared statement reused for each insert";
?>
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
आम गलतियां
  1. user input को SQL string में concatenate करना और फिर prepare call करना, जो prepared statements द्वारा दी गई protection को defeat कर देता है।
  2. prepare() के बाद execute() call करना भूल जाना, ताकि query कभी न चले।
  3. placeholders से अलग संख्या में values bind करना, जो एक error का कारण बनता है।

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.