What Are Prepared Statements? Prevent SQL Injection | CodeZips

If you have seen the advice “always use prepared statements” and wondered what that actually means and why it matters so much, this guide explains it clearly. Prepared statements are the single most important habit for writing secure database code, they are what stops SQL injection, one of the most common and dangerous web vulnerabilities. Here is what they are, how they work, and how to use them, with before-and-after examples.

This is the concept behind the safe query code in most PHP tutorials. Once you understand why prepared statements matter, the “always use them” advice stops being a rule you follow blindly and becomes something you understand.
What this covers
  1. What SQL injection actually is
  2. A concrete example of the danger
  3. What a prepared statement is
  4. How prepared statements stop the attack
  5. Using them in PHP (PDO)
  6. The simple rule to remember

1. What SQL injection actually is

SQL injection is when an attacker types database commands into a normal input field (like a login box or search bar), and your code accidentally runs them as part of your database query. It happens when you build a query by gluing user input directly into the SQL string. The database cannot tell the difference between your intended command and the attacker’s injected command, so it runs both.

2. A concrete example of the danger

Imagine a login query built the unsafe way, by putting the user’s input straight into the SQL:

// UNSAFE: user input glued directly into the query
$username = $_POST['username'];
$password = $_POST['password'];

$sql = "SELECT * FROM users
        WHERE username = '$username'
        AND password = '$password'";

Now imagine an attacker types this into the username field:

' OR '1'='1

Your query becomes:

SELECT * FROM users WHERE username = '' OR '1'='1' AND ...

Because '1'='1' is always true, this can return all users and potentially log the attacker in without a valid password. With more advanced input, an attacker could read, change, or even delete your entire database. This is why SQL injection is so dangerous, and it is shockingly easy to fall victim to if you build queries by gluing in input.

The root cause is mixing your command and the user’s data into one string. The database then treats the attacker’s input as part of the command. Prepared statements fix exactly this by keeping the two separate.

3. What a prepared statement is

A prepared statement is a way of sending a query to the database in two separate parts: first the command with placeholders where values will go, and then the actual values, sent separately. You are essentially telling the database: “here is the shape of the query, and here, separately, are the values to fill in.”

Because the values are sent apart from the command, the database always treats them as pure data, never as part of the SQL. So even if a value contains something that looks like a SQL command, it is treated as a harmless string, not executed.

4. How prepared statements stop the attack

Here is the same login, written safely with a prepared statement:

// SAFE: placeholders, values sent separately
$sql = "SELECT * FROM users WHERE username = ? AND password = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$username, $password]);

Now if the attacker types ' OR '1'='1 into the username, it does not break anything. The database looks for a user whose username is literally the text ' OR '1'='1, which does not exist, so nothing matches. The malicious input is treated as an ordinary (wrong) username, not as a command. The attack simply fails. That is the entire protection: the command and the data never mix.

5. Using them in PHP (PDO)

In PDO, the pattern is always the same three steps: write the query with ? placeholders, prepare it, then execute with the values in an array.

// insert, safely
$stmt = $pdo->prepare(
  "INSERT INTO users (name, email) VALUES (?, ?)"
);
$stmt->execute([$name, $email]);

// select by id, safely
$stmt = $pdo->prepare("SELECT * FROM products WHERE id = ?");
$stmt->execute([$id]);
$product = $stmt->fetch();

You can also use named placeholders (like :name) instead of ? if you find them clearer:

$stmt = $pdo->prepare(
  "INSERT INTO users (name, email) VALUES (:name, :email)"
);
$stmt->execute([':name' => $name, ':email' => $email]);
Both ? and named placeholders are equally safe. Named ones can be easier to read in queries with many values, because you can see which value goes where. Use whichever you prefer, the security is identical.

6. The simple rule to remember

You do not need to analyze every query for danger. Just follow one rule, and you are protected:

Never put a variable directly inside a SQL string. Any value that comes from a user, a form, a URL, or anywhere outside your code, goes in through a placeholder and execute(), never glued into the query text.

Follow that one habit everywhere, and SQL injection essentially cannot happen in your code. It is the single most valuable security habit a beginner can build.

Every database query in the projects on CodeZips uses prepared statements for exactly this reason, it is what makes the login systems and data forms safe. Browse the ready-to-run PHP projects with full source code to see prepared statements used throughout complete, working applications, and see the related guides on connecting with PDO and building a secure login system.

Frequently asked questions

Do prepared statements completely prevent SQL injection?

For the values you pass through placeholders, yes, they fully prevent injection, because the data is never treated as SQL. The one thing placeholders cannot parameterize is structural parts like table or column names; those should never come from user input directly. For normal values (the vast majority of cases), prepared statements are complete protection.

Are prepared statements slower?

The difference is negligible for typical applications, and in some cases repeated prepared statements are actually faster. Security is well worth any tiny overhead. Never avoid them for performance reasons.

Should I use ? or named placeholders?

Both are equally safe. Question marks are shorter; named placeholders (:name) are clearer in queries with many values. It is purely a readability preference.

Does this apply to MySQLi too, or only PDO?

Both PDO and MySQLi support prepared statements and both protect against injection. The syntax differs slightly, but the concept and the protection are the same. This guide uses PDO, which many developers prefer for its cleaner interface.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top