SQL injection occurs when untrusted input changes the structure of a SQL statement.
The examples focus on the operation itself, including the important distinction: Escaping HTML prevents XSS, not SQL injection.
What It Does
Use the examples below to observe the behavior on a small dataset before extending it to application code.
Before You Start
Read the input requirements before applying this pattern to production data.
Example 1: Basic Use
A parameter is treated as data, even when the input contains SQL-like characters. Table and column names still need allowlists.
<?php
$pdo = new PDO(
"mysql:host=" . (getenv("DB_HOST") ?: "127.0.0.1") . ";dbname=" . (getenv("DB_NAME") ?: "demo") . ";charset=utf8mb4",
getenv("DB_USER") ?: "app",
getenv("DB_PASSWORD") ?: "",
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_EMULATE_PREPARES => false]
);
$email = '[email protected]';
$statement = $pdo->prepare("SELECT id FROM users WHERE email = :email");
$statement->execute(["email" => $email]);
$row = $statement->fetch(PDO::FETCH_ASSOC);
echo $row["id"] ?? "not found";
This example is meant for a configured application environment; output depends on the installed extension, external service, or database contents.
Example 2: Checking Behavior
A parameter is treated as data, even when the input contains SQL-like characters. Table and column names still need allowlists.
<?php
$pdo = new PDO(
"mysql:host=" . (getenv("DB_HOST") ?: "127.0.0.1") . ";dbname=" . (getenv("DB_NAME") ?: "demo") . ";charset=utf8mb4",
getenv("DB_USER") ?: "app",
getenv("DB_PASSWORD") ?: "",
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_EMULATE_PREPARES => false]
);
$email = '[email protected]';
$statement = $pdo->prepare("SELECT id FROM users WHERE email = :email");
$statement->execute(["email" => $email]);
$row = $statement->fetch(PDO::FETCH_ASSOC);
echo $row["id"] ?? "not found";
This example is meant for a configured application environment; output depends on the installed extension, external service, or database contents.
Example 3: Practical Example
A parameter is treated as data, even when the input contains SQL-like characters. Table and column names still need allowlists.
<?php
$pdo = new PDO(
"mysql:host=" . (getenv("DB_HOST") ?: "127.0.0.1") . ";dbname=" . (getenv("DB_NAME") ?: "demo") . ";charset=utf8mb4",
getenv("DB_USER") ?: "app",
getenv("DB_PASSWORD") ?: "",
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_EMULATE_PREPARES => false]
);
$email = '[email protected]';
$statement = $pdo->prepare("SELECT id FROM users WHERE email = :email");
$statement->execute(["email" => $email]);
$row = $statement->fetch(PDO::FETCH_ASSOC);
echo $row["id"] ?? "not found";
This example is meant for a configured application environment; output depends on the installed extension, external service, or database contents.
Important Behavior and Edge Cases
Bound parameters protect data values; SQL identifiers and ORDER BY directions require allowlists.
Comparison with Related Approaches
| Approach | Difference |
|---|---|
| PHP SQL Injection Explained for Beginners | SQL injection occurs when untrusted input changes the structure of a SQL statement. |
| Related API or alternative | Escaping HTML prevents XSS, not SQL injection. |
Common Beginner Mistakes
| Mistake | Correct approach |
|---|---|
| Ignoring the operation-specific limits | Bound parameters protect data values; SQL identifiers and ORDER BY directions require allowlists. |
| Confusing it with a related API | Escaping HTML prevents XSS, not SQL injection. |
Key Takeaways
- SQL injection occurs when untrusted input changes the structure of a SQL statement.
- Bound parameters protect data values; SQL identifiers and ORDER BY directions require allowlists.
- Escaping HTML prevents XSS, not SQL injection.
Use PHP SQL Injection Explained for Beginners when its documented behavior matches the problem. Test the relevant edge cases in your own runtime before deploying it.