PHP / CHAPTER 11

Prepared statements and database boundaries

Advanced

Separate SQL structure from data and preserve transaction semantics.

By the end of this chapter

  • Bind values instead of concatenating SQL
  • Keep identifier selection under an allowlist
  • Use transactions for all-or-nothing work

The idea

A prepared statement separates SQL structure from parameter values. Bind user-provided values through placeholders instead of concatenating them into SQL text. This protects the statement’s structure and makes quoting responsibilities explicit. Placeholders represent values, not arbitrary table names, column names, or keywords, so dynamic identifiers require a controlled selection from known allowed choices.

A transaction groups related changes under one commit decision. Validate inputs first, begin the transaction at the appropriate boundary, and roll back when one required step fails. Parameter binding and transactions solve different problems: safe values do not automatically make several updates atomic. Preserve useful errors for the caller, and never report success merely because the first statement ran when later required work failed.

PHP example
<?php
// Given a PDO connection $db with a tasks table:
$sql="SELECT id FROM tasks WHERE status = :status ORDER BY id";
$stmt=$db->prepare($sql);
$stmt->execute(["status"=>"open"]);
// fetchAll(PDO::FETCH_COLUMN) now obtains matching IDs.
echo "Query executed with a bound status\n";
Result
Query executed with a bound status

The example assumes a configured connection and table; the status remains data bound to a fixed query structure.

Try it yourself

Choose an ordering column from an allowlist, then bind the requested status as a value.

Use your own editor for this exercise. Runnable challenges on CodeQuest are available for JavaScript, Python, and SQL.

CHECK YOUR UNDERSTANDING

Chapter checkpoint

Which part of a query can a value placeholder represent?