Prepared statements help keep your database safe and make your code faster when running similar queries many times.
Prepared statements and why they matter in PHP
<?php // Prepare the SQL with placeholders $stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email'); // Bind values to placeholders $stmt->bindParam(':email', $email); // Execute the statement $stmt->execute(); // Fetch results $results = $stmt->fetchAll(); ?>
Placeholders like :email are used instead of putting values directly in the query.
Binding values separately helps prevent harmful input from breaking your query.
<?php $stmt = $pdo->prepare('INSERT INTO users (name, age) VALUES (:name, :age)'); $stmt->execute(['name' => 'Alice', 'age' => 30]); ?>
<?php $stmt = $pdo->prepare('SELECT * FROM products WHERE price < ?'); $stmt->execute([100]); ?>
<?php $email = 'user@example.com'; $stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email'); $stmt->bindParam(':email', $email); $stmt->execute(); ?>
This program creates a small database in memory, adds two users safely using prepared statements, then searches for one user by email and prints the result.
<?php // Connect to database using PDO $pdo = new PDO('sqlite::memory:'); // Create a simple table $pdo->exec('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)'); // Prepare an INSERT statement $stmt = $pdo->prepare('INSERT INTO users (name, email) VALUES (:name, :email)'); // Insert two users safely $stmt->execute(['name' => 'John', 'email' => 'john@example.com']); $stmt->execute(['name' => 'Jane', 'email' => 'jane@example.com']); // Prepare a SELECT statement $select = $pdo->prepare('SELECT * FROM users WHERE email = :email'); // Search for Jane by email $searchEmail = 'jane@example.com'; $select->execute(['email' => $searchEmail]); // Fetch and print the result $user = $select->fetch(PDO::FETCH_ASSOC); if ($user) { echo "Found user: {$user['name']} with email {$user['email']}\n"; } else { echo "User not found.\n"; } ?>
Always use prepared statements when inserting or searching with user input to avoid security risks.
Prepared statements can improve performance if you run the same query many times with different data.
PDO is a common PHP extension that supports prepared statements with many databases.
Prepared statements separate SQL code from data to keep your database safe.
They help prevent hackers from changing your queries with bad input.
Using prepared statements is a best practice for working with databases in PHP.
Practice
prepared statements in PHP when working with databases?Solution
Step 1: Understand the purpose of prepared statements
Prepared statements separate SQL code from user data, preventing malicious input from changing the query.Step 2: Identify the security benefit
This separation protects against SQL injection, a common hacking method.Final Answer:
To protect the database from SQL injection attacks -> Option AQuick Check:
Security = Protect from SQL injection [OK]
- Thinking prepared statements speed up queries significantly
- Confusing prepared statements with data storage
- Believing prepared statements create tables automatically
Solution
Step 1: Recall PDO method for preparing statements
The correct method to prepare a statement isprepare(), which sets up the SQL with placeholders.Step 2: Check the options for correct method usage
Only $stmt = $pdo->prepare('SELECT * FROM users WHERE id = ?'); usesprepare()correctly with a SQL string containing a placeholder.Final Answer:
$stmt = $pdo->prepare('SELECT * FROM users WHERE id = ?'); -> Option AQuick Check:
PDO prepare() method = $stmt = $pdo->prepare('SELECT * FROM users WHERE id = ?'); [OK]
- Using query() instead of prepare() for statements with placeholders
- Trying to execute SQL directly with execute() without preparing
- Confusing fetch() with prepare()
$pdo = new PDO('sqlite::memory:');
$pdo->exec('CREATE TABLE users (id INTEGER, name TEXT)');
$stmt = $pdo->prepare('INSERT INTO users (id, name) VALUES (?, ?)');
$stmt->execute([1, 'Alice']);
$stmt->execute([2, 'Bob']);
$stmt = $pdo->prepare('SELECT name FROM users WHERE id = ?');
$stmt->execute([2]);
echo $stmt->fetchColumn();Solution
Step 1: Insert two users into the table
The code inserts two rows: id=1 with name 'Alice' and id=2 with name 'Bob'.Step 2: Select the name where id = 2
The prepared statement selects the name for id=2, which is 'Bob'.Final Answer:
Bob -> Option CQuick Check:
Selected name for id=2 = Bob [OK]
- Confusing the order of inserted rows
- Expecting the first inserted name instead of the queried one
- Assuming an error due to missing database file
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email');
$stmt->execute('user@example.com');
$result = $stmt->fetchAll();Solution
Step 1: Check the execute() method argument
When using named placeholders like ':email', execute() expects an associative array with keys matching placeholders.Step 2: Identify the incorrect argument type
The code passes a string directly instead of an array like ['email' => 'user@example.com'].Final Answer:
The execute() method should receive an array, not a string -> Option DQuick Check:
execute() needs array for named placeholders [OK]
- Passing a string instead of an array to execute()
- Forgetting to match placeholder names in the array keys
- Thinking fetchAll() cannot follow execute()
Solution
Step 1: Understand how to use named placeholders for multiple inserts
Using named placeholders (:id, :name) allows binding values clearly for each execute call.Step 2: Check each option for correct usage
Only $stmt = $pdo->prepare('INSERT INTO users (id, name) VALUES (:id, :name)'); $stmt->execute(['id' => 1, 'name' => 'Alice']); $stmt->execute(['id' => 2, 'name' => 'Bob']); correctly prepares once and executes twice with separate associative arrays for each user.Step 3: Identify errors in other options
$stmt = $pdo->prepare('INSERT INTO users (id, name) VALUES (?, ?)'); $stmt->execute(1, 'Alice'); $stmt->execute(2, 'Bob'); incorrectly passes parameters directly to execute() without an array; $pdo->exec("INSERT INTO users (id, name) VALUES (1, 'Alice'), (2, 'Bob')"); uses exec() without preparing; $stmt = $pdo->prepare('INSERT INTO users (id, name) VALUES (:id, :name)'); $stmt->execute(['id' => 1, 'name' => 'Alice', 'id' => 2, 'name' => 'Bob']); tries to pass multiple users in one execute call incorrectly.Final Answer:
$stmt = $pdo->prepare('INSERT INTO users (id, name) VALUES (:id, :name)'); $stmt->execute(['id' => 1, 'name' => 'Alice']); $stmt->execute(['id' => 2, 'name' => 'Bob']); -> Option BQuick Check:
Named placeholders + separate execute calls = $stmt = $pdo->prepare('INSERT INTO users (id, name) VALUES (:id, :name)'); $stmt->execute(['id' => 1, 'name' => 'Alice']); $stmt->execute(['id' => 2, 'name' => 'Bob']); [OK]
- Passing multiple records in one execute call incorrectly
- Not using prepared statements and risking SQL injection
- Passing parameters to execute() without an array for positional placeholders
Ready to prove it?
Pass the test and this pattern moves unknown
