When using PHP and PDO to operate databases on a daily basis, PDOStatement::fetchObject is a very convenient method, which can directly convert query results into objects. However, by default it will only create and will not automatically handle more complex nested object structures . If you want the result to contain nested objects, such as a User object to nest a Profile object, you need to process it yourself.
Let’s take a look at how to achieve this goal step by step.
Suppose you have two tables like this:
CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(100),
profile_id INT
);
CREATE TABLE profiles (
id INT PRIMARY KEY,
bio TEXT,
avatar_url VARCHAR(255)
);
You want to query user data and turn the result into a User object while nesting a Profile object.
For example, I hope to get a structure similar to this:
User {
id => 1,
name => 'Alice',
profile => Profile {
id => 2,
bio => 'Hello world!',
avatar_url => 'https://gitbox.net/uploads/avatar.jpg'
}
}
We need to create PHP classes for User and Profile :
class Profile {
public int $id;
public string $bio;
public string $avatar_url;
}
class User {
public int $id;
public string $name;
public Profile $profile;
}
You can use JOIN query to retrieve the data from two tables at once:
$sql = "
SELECT
u.id AS user_id,
u.name AS user_name,
p.id AS profile_id,
p.bio AS profile_bio,
p.avatar_url AS profile_avatar_url
FROM users u
JOIN profiles p ON u.profile_id = p.id
";
$stmt = $pdo->query($sql);
Since fetchObject only maps one layer of data by default, we need to assemble nested objects by ourselves. You can do this:
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$user = new User();
$user->id = (int) $row['user_id'];
$user->name = $row['user_name'];
$profile = new Profile();
$profile->id = (int) $row['profile_id'];
$profile->bio = $row['profile_bio'];
$profile->avatar_url = $row['profile_avatar_url'];
$user->profile = $profile;
// Now $user It contains nesting Profile The object of
var_dump($user);
}
If you often need to deal with this, you can encapsulate it into a gadget function:
function mapRowToUser(array $row): User {
$user = new User();
$user->id = (int) $row['user_id'];
$user->name = $row['user_name'];
$profile = new Profile();
$profile->id = (int) $row['profile_id'];
$profile->bio = $row['profile_bio'];
$profile->avatar_url = $row['profile_avatar_url'];
$user->profile = $profile;
return $user;
}
// use
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$user = mapRowToUser($row);
var_dump($user);
}
Although PDOStatement::fetchObject itself cannot create nested objects directly, it can be very flexible to implement complex data structure mapping through manual assignment and encapsulation. This method is clearer, more secure than simple array processing, and more in line with modern PHP object-oriented development habits.
If you want to further simplify, you can consider combining ORM tools (such as Eloquent, Doctrine) to automatically process these mappings, but for lightweight projects, this manual mapping method is already very sufficient!