ZetCode

PHP PDOStatement::fetchObject Method

last modified April 19, 2025

The PDOStatement::fetchObject method fetches the next row from a result set as an object of the specified class. It provides an object-oriented way to access database records.

Basic Definition

PDOStatement::fetchObject retrieves the next row from a result set as an object. It can create instances of a specified class with properties mapped to column names.

Syntax: public PDOStatement::fetchObject(string $class = "stdClass", array $constructorArgs = []): object|false. The first parameter is the class name, defaulting to stdClass.

Basic fetchObject Usage

This shows the simplest way to use fetchObject with the default stdClass.

fetch_object_basic.php
<?php

declare(strict_types=1);

try {
    $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    $stmt = $pdo->query('SELECT id, name, email FROM users LIMIT 1');
    $user = $stmt->fetchObject();
    
    echo "User: {$user->name} ({$user->email})";
} catch (PDOException $e) {
    echo "Error: " . $e->getMessage();
}

This fetches a single row as a stdClass object. Column names become object properties. The properties can be accessed using the object operator (->).

Fetching into Custom Class

This demonstrates fetching data directly into a custom class instance.

fetch_object_custom_class.php
<?php

declare(strict_types=1);

class User {
    public int $id;
    public string $name;
    public string $email;
    
    public function getInfo(): string {
        return "{$this->name} <{$this->email}>";
    }
}

try {
    $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    $stmt = $pdo->query('SELECT id, name, email FROM users LIMIT 1');
    $user = $stmt->fetchObject('User');
    
    echo $user->getInfo();
} catch (PDOException $e) {
    echo "Error: " . $e->getMessage();
}

This creates a User object with the database row data. The class must have properties matching column names. Methods of the class become available.

With Constructor Arguments

This shows how to pass arguments to the class constructor during fetching.

fetch_object_constructor_args.php
<?php

declare(strict_types=1);

class UserProfile {
    public function __construct(
        public int $id,
        public string $name,
        public string $role = 'user'
    ) {}
    
    public function display(): string {
        return "{$this->name} ({$this->role})";
    }
}

try {
    $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    $stmt = $pdo->query('SELECT id, name FROM users LIMIT 1');
    $user = $stmt->fetchObject('UserProfile', ['admin']);
    
    echo $user->display();
} catch (PDOException $e) {
    echo "Error: " . $e->getMessage();
}

This passes 'admin' as the role parameter to the constructor. The database columns map to the remaining constructor parameters. Properties are promoted.

Fetching Multiple Rows

This demonstrates using fetchObject in a loop to process multiple rows.

fetch_object_multiple_rows.php
<?php

declare(strict_types=1);

class Product {
    public int $id;
    public string $name;
    public float $price;
    
    public function formatPrice(): string {
        return '$' . number_format($this->price, 2);
    }
}

try {
    $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    $stmt = $pdo->query('SELECT id, name, price FROM products');
    
    while ($product = $stmt->fetchObject('Product')) {
        echo "{$product->name}: {$product->formatPrice()}\n";
    }
} catch (PDOException $e) {
    echo "Error: " . $e->getMessage();
}

This loops through all products, creating a Product object for each row. The formatPrice method formats the price consistently across all products.

With Prepared Statements

This combines fetchObject with prepared statements for secure queries.

fetch_object_prepared.php
<?php

declare(strict_types=1);

class Customer {
    public int $id;
    public string $name;
    public string $email;
    public DateTime $created_at;
}

try {
    $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    $stmt = $pdo->prepare('SELECT id, name, email, created_at FROM customers WHERE id = ?');
    $stmt->execute([42]);
    
    $customer = $stmt->fetchObject('Customer');
    
    if ($customer) {
        $date = $customer->created_at->format('Y-m-d');
        echo "Customer {$customer->name} joined on {$date}";
    }
} catch (PDOException $e) {
    echo "Error: " . $e->getMessage();
}

This safely fetches a customer by ID using a prepared statement. The created_at column is automatically converted to a DateTime object.

Handling NULL Values

This shows how fetchObject handles NULL database values in objects.

fetch_object_null_values.php
<?php

declare(strict_types=1);

class Employee {
    public ?int $manager_id = null;
    public string $name;
    public ?string $department = null;
}

try {
    $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    $stmt = $pdo->query('SELECT name, manager_id, department FROM employees LIMIT 1');
    $employee = $stmt->fetchObject('Employee');
    
    $managerText = $employee->manager_id ? "Manager ID: {$employee->manager_id}" : "No manager";
    echo "{$employee->name}, {$managerText}";
} catch (PDOException $e) {
    echo "Error: " . $e->getMessage();
}

This properly handles NULL database values by using nullable types. The properties are initialized to NULL if the database value is NULL.

Advanced Class Hydration

This demonstrates more complex object hydration with private properties.

fetch_object_advanced_hydration.php
<?php

declare(strict_types=1);

class Order {
    private int $id;
    private float $total;
    private DateTimeImmutable $order_date;
    
    public function getId(): int {
        return $this->id;
    }
    
    public function getTotal(): float {
        return $this->total;
    }
    
    public function getOrderDate(): DateTimeImmutable {
        return $this->order_date;
    }
    
    public function getFormattedDate(): string {
        return $this->order_date->format('M j, Y');
    }
}

try {
    $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    $stmt = $pdo->query('SELECT id, total, order_date FROM orders LIMIT 1');
    $order = $stmt->fetchObject('Order');
    
    echo "Order #{$order->getId()} on {$order->getFormattedDate()}";
    echo "Total: $" . number_format($order->getTotal(), 2);
} catch (PDOException $e) {
    echo "Error: " . $e->getMessage();
}

This hydrates an Order object with private properties. The class provides getter methods to access the data. The order_date is converted to DateTimeImmutable.

Best Practices

Source

PHP fetchObject Documentation

This tutorial covered the PDOStatement::fetchObject method with practical examples showing different usage scenarios and best practices.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all PHP PDO Functions.