Prepared Statement
Also Known As
parameterised query
prepared statement SQL
parameterized query
TL;DR
A parameterised SQL query where data placeholders are bound separately from the query structure, preventing SQL injection.
Explanation
A prepared statement separates the SQL structure (sent to the database first) from the data values (bound and sent separately). The database parses the query once and treats the bound values as data, never as SQL syntax — making SQL injection structurally impossible regardless of what the user submits. Both PDO (with named :param or positional ? placeholders) and MySQLi (with bind_param()) support prepared statements. Never use string concatenation to build SQL queries.
Common Misconception
✗ Prepared statements with PDO::ATTR_EMULATE_PREPARES enabled are fully safe. Emulated prepared statements do client-side string interpolation rather than sending parameters separately to the database — disable emulation with $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false) for true parameterisation.
Why It Matters
Prepared statements are the only reliable defence against SQL injection — user data is never interpreted as SQL syntax. They also improve performance when the same query runs multiple times because the database parses it once.
Common Mistakes
- Binding only some parameters and concatenating the rest — every external value must be bound.
- Using PDO emulated prepares (the default) which can be bypassable — set PDO::ATTR_EMULATE_PREPARES to false.
- Confusing query parameters with identifiers — you cannot bind table or column names, only values.
- Reusing a statement handle but forgetting to call execute() again after changing bound values.
Code Examples
✗ Vulnerable
$id = $_GET['id'];
$rows = $pdo->query("SELECT * FROM users WHERE id = $id"); // SQLi
✓ Fixed
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$_GET['id']]);
$user = $stmt->fetch();
References
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
13 Mar 2026
Edited
22 Mar 2026
Views
34
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 1
No pings yesterday
Perplexity 9
Amazonbot 7
Ahrefs 5
Unknown AI 2
Google 2
SEMrush 2
ChatGPT 2
Also referenced
How they use it
crawler 26
crawler_json 2
pre-tracking 1
Related categories
⚡
DEV INTEL
Tools & Severity
🔴 Critical
⚙ Fix effort: Low
⚡ Quick Fix
Replace ->query("...{$var}") with ->prepare('...:param') followed by ->execute([':param' => $var]) — the driver handles escaping automatically
📦 Applies To
PHP 5.1+
web
cli
queue-worker
🔗 Prerequisites
🔍 Detection Hints
->query() or ->exec() with string interpolation of variables; no prepare()/execute() pattern
Auto-detectable:
✓ Yes
semgrep
psalm
phpstan
⚠ Related Problems
🤖 AI Agent
Confidence: High
False Positives: Low
✓ Auto-fixable
Fix: Low
Context: Line
CWE-89