← PHP for real applications
03 / 8 · 23 MIN

Data with parameters

Keep SQL instructions separate from input values.

Separate instructions from data

A prepared statement lets values be passed as parameters rather than concatenated into SQL. This reduces the risk of input changing the query structure. Parameters represent values; dynamic table or column names need an explicit allowlist.

Transactions and ownership

Use a transaction when several changes must commit together. Also enforce authorization: a parameterized query can still return someone else’s record if it does not restrict ownership. Query safety and authorization solve different problems.

Guided workplace application

A private-note query needs two decisions: separate values from SQL structure and restrict the resource to authorized scope. Use parameters for IDs and text; the authenticated user must come from server-validated context, not an arbitrary owner_id supplied in the request. To sort by title or created_at, map the received option to one of the fixed allowed columns. Do not expect ORDER BY:column to turn a parameter into an identifier. In IN, a comma-separated string does not become a value list either: build one placeholder per validated value and define empty-list behavior. Transactions group writes under engine guarantees but do not grant permission or automatically eliminate concurrency.

$stmt = $pdo->prepare(
 "SELECT id, title FROM notes WHERE id =:id AND user_id =:user"
);
$stmt->execute(["id" => $noteId, "user" => $currentUserId])
IN PRACTICE

A user changes a note identifier in the URL. The application must look up the note within the authenticated account and refuse access to other accounts’ notes.

Common pitfalls

Binding column names as values; concatenating supplied lists; trusting client owner_id.

Related topics: Security at the web boundary · PDO transactions and partial failures

Take this idea with you

Parameterize values and verify the owner of every protected resource.

Create account

Reference: PHP manual: PDO prepared statements · PHP 8.5 reference; DR PHP 2026.2; new fixtures executed on PHP 8.3.17