Current Location: Home> Latest Articles> How to deal with the return value of PDOStatement::fetchObject when the database column type is inconsistent

How to deal with the return value of PDOStatement::fetchObject when the database column type is inconsistent

gitbox 2025-05-29

PDOStatement::fetchObject is a very practical method when operating a database using PDO in PHP. It can return a record as an object and assign the value of each column to the object's properties. However, when the type of the database column does not match the expected type of the target object property, some confusing problems can arise, such as type mismatch, implicit conversion errors, or behavioral exceptions.

Problem background

 class User {
    public int $id;
    public string $name;
    public bool $is_active;
}

$stmt = $pdo->query('SELECT id, name, is_active FROM users');
$user = $stmt->fetchObject('User');

Suppose that the is_active column in the users table is a TINYINT(1) type, and in the User class we define the bool type. If the value of is_active is 1 or 0 , you may expect it to be automatically converted to true or false . But in reality, PHP will directly assign values ​​of type int , which will cause types inconsistencies and even directly throw errors in strict type mode.

The behavior principle of fetchObject

Inside fetchObject , the database field is mapped to object properties through __set() or direct assignment. It does not perform type conversion, but directly assigns the value according to the original value of the database. This means:

  • The INT value in the database will become PHP int

  • VARCHAR will become string

  • Although TINYINT(1) is often used for boolean values, it is actually an integer type

After the type prompt of declare(strict_types=1) or PHP 8.2+ is strengthened, a type mismatch will cause a runtime error.

Solution

Method 1: Manual type conversion (recommended)

A safe approach is to manually convert each field to the appropriate type after getting the object. This method is the safest and most readable.

 $user = $stmt->fetchObject('User');
if ($user !== false) {
    $user->id = (int)$user->id;
    $user->name = (string)$user->name;
    $user->is_active = (bool)$user->is_active;
}

Method 2: Use the constructor to receive parameters

fetchObject supports passing in constructor parameters. If you design a constructor that accepts initialized data, you can implement type conversion gracefully:

 class User {
    public function __construct(
        public int $id,
        public string $name,
        public bool $is_active
    ) {}
}

$stmt = $pdo->query('SELECT id, name, is_active FROM users');
$user = $stmt->fetchObject('User');

But the problem here is: if the database column order is inconsistent or the fields do not match exactly, an exception may be thrown.

Method 3: Customize the factory class for processing

If the data volume is large or the object structure is complex, consider using a factory class to handle the transformation logic.

 class UserFactory {
    public static function fromDb(stdClass $row): User {
        return new User(
            (int)$row->id,
            (string)$row->name,
            (bool)$row->is_active
        );
    }
}

$stmt = $pdo->query('SELECT id, name, is_active FROM users');
$row = $stmt->fetchObject();
if ($row !== false) {
    $user = UserFactory::fromDb($row);
}

Although this has more code, the structure is clear and the logic is centralized, making it easy to unit testing and maintenance.

Method 4: Set the FETCH_CLASS mode of PDO (limited support)

You can also use PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE mode, but you also need to pay attention to the type conversion problem. PHP does not make type inference internally.

 $stmt = $pdo->query('SELECT id, name, is_active FROM users');
$stmt->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'User');
$user = $stmt->fetch();

As mentioned above, although the code is simplified, it still cannot solve the problem of type mandatory.

summary

When using PDOStatement::fetchObject for object extraction, be sure to pay attention to the correspondence between database field types and object attribute types. PHP does not automatically perform intelligent conversions, especially after turning on the type prompt, developers need to explicitly handle the conversion logic. The most recommended way is to decouple data extraction and object construction, such as using factory classes or manual transformations, thereby improving the robustness and maintainability of your code.

For more related examples, please refer to: https://gitbox.net/pdo/fetchobject-type-conversion