CRUD with PDO & Prepared Statements
Create, read, update and delete database records safely — using prepared statements to block SQL injection.
What you will learn
- Perform full CRUD with PDO
- Use prepared statements
- Prevent SQL injection
Prepared statements = safe queries
CRUD stands for the four things every data app does: Create, Read, Update, Delete. Never put user input directly into SQL — that allows SQL injection attacks. Instead use prepared statements: you write the SQL with ? placeholders, then hand PDO the real values separately and it fills them in safely.
Every prepared statement follows the same two steps:
- Prepare the SQL with
$pdo->prepare(...), using?where each user value will go. - Execute it with
$stmt->execute([...]), passing the actual values in an array (in the same order as the?marks). - For reads, fetch the result afterwards with
fetch()(one row) orfetchAll()(all rows).
<?php
// CREATE — safe insert with placeholders
$stmt = $pdo->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
$stmt->execute([$name, $email]);
// READ one
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$id]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
// UPDATE
$stmt = $pdo->prepare("UPDATE users SET name = ? WHERE id = ?");
$stmt->execute([$newName, $id]);
// DELETE
$stmt = $pdo->prepare("DELETE FROM users WHERE id = ?");
$stmt->execute([$id]);
?>Look at each block. CREATE prepares an INSERT with two ? marks, then execute([$name, $email]) slots those values in — first ? gets $name, second gets $email. READ uses one ? for the id, runs it, then fetch() returns that single matching row. UPDATE has two ? — note the order: $newName fills the SET name = ? and $id fills the WHERE id = ?. DELETE removes the row whose id matches its ?.
Note: Output:
(These statements change or read the database rather than print.) After CREATE, a new row exists. After READ, $user holds something like ["id" => 1, "name" => "Asha", "email" => "asha@x.com"]. UPDATE changes that row’s name; DELETE removes it. The order of values in execute([...]) must match the order of the ? marks.
Watch out: Always use prepared statements (the ? placeholders) for any value that comes from a user. Building SQL by joining strings ("... WHERE id = " . $id) is the classic SQL-injection vulnerability.
Tip: This raw PDO is exactly what frameworks like Laravel wrap in a beautiful, simple interface (Eloquent). Understanding it here means you will know what Laravel is doing under the hood.
Q. How do prepared statements protect you?
✍️ Practice
- Insert a new record using a prepared statement.
- Update and delete a record by id with placeholders.
🏠 Homework
- Build all four CRUD operations for a
productstable using prepared statements.