Use a bound primary key to remove exactly the intended record.
The examples focus on the operation itself, including the important distinction: SELECT reads rows; DELETE is a write operation.
What It Does
Use the examples below to observe the behavior on a small dataset before extending it to application code.
Before You Start
The examples use PHP 8.2+ features where shown. Database snippets require the corresponding PDO driver, demo tables, and credentials configured outside source code.
Example 1: Basic Use
The delete runs in a transaction; this example treats zero deleted rows as an application error.
<?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]
);
$id = 6;
$pdo->beginTransaction();
try {
$stmt = $pdo->prepare("DELETE FROM users WHERE id = ?");
$stmt->execute([$id]);
if ($stmt->rowCount() !== 1) { throw new RuntimeException("No matching user"); }
$pdo->commit();
} catch (Throwable $e) { if ($pdo->inTransaction()) { $pdo->rollBack(); } throw $e; }
This example is meant for a configured application environment; output depends on the installed extension, external service, or database contents.
Example 2: Checking Behavior
The delete runs in a transaction; this example treats zero deleted rows as an application error.
<?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]
);
$id = 9;
$pdo->beginTransaction();
try {
$stmt = $pdo->prepare("DELETE FROM users WHERE id = ?");
$stmt->execute([$id]);
if ($stmt->rowCount() !== 1) { throw new RuntimeException("No matching user"); }
$pdo->commit();
} catch (Throwable $e) { if ($pdo->inTransaction()) { $pdo->rollBack(); } throw $e; }
This example is meant for a configured application environment; output depends on the installed extension, external service, or database contents.
Example 3: Practical Example
The delete runs in a transaction; this example treats zero deleted rows as an application error.
<?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]
);
$id = 17;
$pdo->beginTransaction();
try {
$stmt = $pdo->prepare("DELETE FROM users WHERE id = ?");
$stmt->execute([$id]);
if ($stmt->rowCount() !== 1) { throw new RuntimeException("No matching user"); }
$pdo->commit();
} catch (Throwable $e) { if ($pdo->inTransaction()) { $pdo->rollBack(); } throw $e; }
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
rowCount reports affected rows, not guaranteed existence before deletion; never construct identifiers from request strings.
Comparison with Related Approaches
| Approach | Difference |
|---|---|
| Deleting Records with PDO | Use a bound primary key to remove exactly the intended record. |
| Related API or alternative | SELECT reads rows; DELETE is a write operation. |
Common Beginner Mistakes
| Mistake | Correct approach |
|---|---|
| Ignoring the operation-specific limits | rowCount reports affected rows, not guaranteed existence before deletion; never construct identifiers from request strings. |
| Confusing it with a related API | SELECT reads rows; DELETE is a write operation. |
Key Takeaways
- Use a bound primary key to remove exactly the intended record.
- rowCount reports affected rows, not guaranteed existence before deletion; never construct identifiers from request strings.
- SELECT reads rows; DELETE is a write operation.
Use Deleting Records with PDO when its documented behavior matches the problem. Test the relevant edge cases in your own runtime before deploying it.