Prepared statements help keep your database safe by stopping bad code from sneaking in. They make sure user input is treated as data, not code.
Preventing injection with prepared statements in PHP
<?php $stmt = $pdo->prepare('SQL query with ? or :named placeholders'); $stmt->execute([$value1, $value2]); // or $stmt->execute(['name' => $value1, 'age' => $value2]);
Use prepare() to create a safe SQL template.
Use execute() to fill in the placeholders with actual values.
? as a placeholder for one value.<?php
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = ?');
$stmt->execute([$email]);:user for clarity.<?php $stmt = $pdo->prepare('SELECT * FROM users WHERE username = :user'); $stmt->execute(['user' => $username]);
<?php $stmt = $pdo->prepare('INSERT INTO products (name, price) VALUES (:name, :price)'); $stmt->execute(['name' => $productName, 'price' => $productPrice]);
This program shows how to safely add and get a user from a database using prepared statements. It stops any harmful input from changing the database commands.
<?php // Connect to database using PDO $pdo = new PDO('sqlite::memory:'); // Create a simple table $pdo->exec('CREATE TABLE users (id INTEGER PRIMARY KEY, username TEXT, email TEXT)'); // User input simulation $username = "alice"; $email = "alice@example.com"; // Prepare statement to insert data safely $stmt = $pdo->prepare('INSERT INTO users (username, email) VALUES (:username, :email)'); $stmt->execute(['username' => $username, 'email' => $email]); // Prepare statement to select data safely $stmt = $pdo->prepare('SELECT id, username, email FROM users WHERE username = :username'); $stmt->execute(['username' => $username]); // Fetch and print result $user = $stmt->fetch(PDO::FETCH_ASSOC); if ($user) { echo "User found: " . $user['username'] . " with email " . $user['email'] . "\n"; } else { echo "User not found.\n"; }
Always use prepared statements when working with user input to avoid SQL injection.
Placeholders can be question marks ? or named like :name. Named placeholders are easier to read.
Prepared statements also help your code run faster if you repeat the same query many times with different values.
Prepared statements keep your database safe by separating code from data.
Use prepare() and execute() to run safe queries.
Always use them when you include user input in SQL commands.
Practice
Solution
Step 1: Understand SQL injection risks
SQL injection happens when user input is mixed directly with SQL code, allowing attackers to change the query.Step 2: Role of prepared statements
Prepared statements separate the SQL code from the data, so user input cannot change the query structure.Final Answer:
To prevent SQL injection by separating SQL code from user data -> Option BQuick Check:
Prepared statements prevent injection = D [OK]
- Thinking prepared statements speed up all queries
- Believing they format output automatically
- Confusing with multiple connections
Solution
Step 1: Check correct prepare syntax
Useprepare()with placeholders like?for parameters.Step 2: Execute with parameters
Callexecute()with an array of values to bind to placeholders.Final Answer:
$stmt = $pdo->prepare('SELECT * FROM users WHERE id = ?'); $stmt->execute([$id]); -> Option AQuick Check:
prepare + execute with array = A [OK]
- Using query() with variables directly
- Putting variables inside prepare() string
- Calling execute() before prepare()
$stmt = $pdo->prepare('SELECT name FROM users WHERE id = ?');
$stmt->execute([2]);
$result = $stmt->fetchColumn();
echo $result;
Assuming the user with id 2 has the name 'Alice'.Solution
Step 1: Understand prepare and execute
The statement prepares a query with a placeholder and executes it with id = 2.Step 2: Fetch the result
fetchColumn()returns the first column of the first row, which is the name 'Alice'.Final Answer:
Alice -> Option CQuick Check:
fetchColumn returns name 'Alice' = C [OK]
- Expecting fetchColumn() to return an array
- Confusing id with name output
- Not passing parameters to execute()
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email');
$stmt->execute(':email' => $email);Solution
Step 1: Check placeholder usage
Named placeholders like:emailare valid in prepare statements.Step 2: Check execute() argument syntax
execute() expects an array, but':email' => $emailis not inside an array here.Final Answer:
The execute() method argument should be an array, but syntax is incorrect -> Option DQuick Check:
execute() needs array argument = A [OK]
- Using wrong placeholder style
- Passing parameters without array brackets
- Calling execute() before prepare()
$users = [ ['name' => 'John', 'email' => 'john@example.com'], ['name' => 'Jane', 'email' => 'jane@example.com'] ]; // Which code below is correct?
Solution
Step 1: Check safe insertion of multiple rows
foreach ($users as $user) { $stmt = $pdo->prepare('INSERT INTO users (name, email) VALUES (?, ?)'); $stmt->execute([$user['name'], $user['email']]); } prepares once per iteration and executes with user data safely bound as parameters.Step 2: Analyze other options
$stmt = $pdo->prepare('INSERT INTO users (name, email) VALUES (?, ?)'); $stmt->execute($users); passes array of arrays directly to execute(), which is invalid. foreach ($users as $user) { $sql = "INSERT INTO users (name, email) VALUES ('{$user['name']}', '{$user['email']}')"; $pdo->query($sql); } uses string interpolation risking injection. $sql = 'INSERT INTO users (name, email) VALUES (?, ?)'; $stmt = $pdo->prepare($sql); $stmt->execute(); calls execute() without parameters.Final Answer:
foreach ($users as $user) { $stmt = $pdo->prepare('INSERT INTO users (name, email) VALUES (?, ?)'); $stmt->execute([$user['name'], $user['email']]); } -> Option AQuick Check:
Prepare and execute per user with parameters = B [OK]
- Passing multidimensional array directly to execute()
- Using string interpolation instead of parameters
- Calling execute() without parameters
Ready to prove it?
Pass the test and this pattern moves unknown
