← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Prepared Statement

php PHP 5.1+ Intermediate

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();

Added 13 Mar 2026
Edited 22 Mar 2026
Views 34
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 2 pings T 0 pings W 0 pings T 0 pings F 1 ping S 2 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 0 pings S 1 ping M 0 pings T 1 ping W 1 ping T 0 pings F 1 ping S
No pings yesterday
Perplexity 9 Amazonbot 7 Ahrefs 5 Unknown AI 2 Google 2 SEMrush 2 ChatGPT 2
crawler 26 crawler_json 2 pre-tracking 1
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

✓ schema.org compliant