Convert database rows into explicit typed domain objects after validation and normalization.
The examples focus on the operation itself, including the important distinction: FETCH_ASSOC returns raw columns; DTO construction enforces application types.
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
Cast DB driver values deliberately and validate domain constraints when constructing typed objects.
<?php
final readonly class UserView {
public function __construct(public int $id, public string $email) {}
public static function fromRow(array $row): self {
return new self((int) $row["id"], (string) $row["email"]);
}
}
$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]
);
$row = $pdo->query("SELECT id, email FROM users ORDER BY id LIMIT 1")->fetch(PDO::FETCH_ASSOC);
if ($row) { $user = UserView::fromRow($row); echo $user->email; }
This example is meant for a configured application environment; output depends on the installed extension, external service, or database contents.
Example 2: Checking Behavior
Cast DB driver values deliberately and validate domain constraints when constructing typed objects. The typed mapping is independent of the SQL row selection.
<?php
final readonly class UserView {
public function __construct(public int $id, public string $email) {}
public static function fromRow(array $row): self {
return new self((int) $row["id"], (string) $row["email"]);
}
}
$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]
);
$row = $pdo->query("SELECT id, email FROM users ORDER BY id DESC LIMIT 1")->fetch(PDO::FETCH_ASSOC);
if ($row) { $user = UserView::fromRow($row); echo $user->email; }
This example is meant for a configured application environment; output depends on the installed extension, external service, or database contents.
Example 3: Practical Example
Cast DB driver values deliberately and validate domain constraints when constructing typed objects. The typed mapping is independent of the SQL row selection.
<?php
final readonly class UserView {
public function __construct(public int $id, public string $email) {}
public static function fromRow(array $row): self {
return new self((int) $row["id"], (string) $row["email"]);
}
}
$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]
);
$row = $pdo->query("SELECT id, email FROM users WHERE active = 1 ORDER BY id LIMIT 1")->fetch(PDO::FETCH_ASSOC);
if ($row) { $user = UserView::fromRow($row); echo $user->email; }
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
PDO often returns numeric values as strings depending on driver and options; cast and validate intentionally.
Comparison with Related Approaches
| Approach | Difference |
|---|---|
| Mapping Database Rows to Typed PHP Objects | Convert database rows into explicit typed domain objects after validation and normalization. |
| Related API or alternative | FETCH_ASSOC returns raw columns; DTO construction enforces application types. |
Common Beginner Mistakes
| Mistake | Correct approach |
|---|---|
| Ignoring the operation-specific limits | PDO often returns numeric values as strings depending on driver and options; cast and validate intentionally. |
| Confusing it with a related API | FETCH_ASSOC returns raw columns; DTO construction enforces application types. |
Key Takeaways
- Convert database rows into explicit typed domain objects after validation and normalization.
- PDO often returns numeric values as strings depending on driver and options; cast and validate intentionally.
- FETCH_ASSOC returns raw columns; DTO construction enforces application types.
Use Mapping Database Rows to Typed PHP Objects when its documented behavior matches the problem. Test the relevant edge cases in your own runtime before deploying it.