When using PHP's PDO to operate the database, the PDOStatement::fetchObject() method is very convenient, and it can directly map the query results into an object. However, when the database field contains (such as DATETIME , TIMESTAMP types), it may encounter some problems directly using fetchObject , such as the date field being processed as a normal string, which makes subsequent formatting and comparisons become troublesome.
This article will explain how to correctly handle these datetime fields when using fetchObject and give practical examples.
Suppose there is a user table user , the structure is as follows:
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
created_at DATETIME NOT NULL
);
Insert a data:
INSERT INTO users (name, created_at) VALUES ('Alice', '2025-04-27 14:30:00');
Use fetchObject to get data:
<?php
$pdo = new PDO('mysql:host=localhost;dbname=test', 'username', 'password');
$stmt = $pdo->query('SELECT * FROM users WHERE id = 1');
$user = $stmt->fetchObject();
echo $user->created_at;
?>
The output is a normal string :
2025-04-27 14:30:00
If you want to add, subtract, format and other operations on created_at , you have to manually convert it with the DateTime class, which is very inelegant.
There are two common ways to handle it gracefully:
After getting the object, immediately convert the date field to the DateTime object.
<?php
$pdo = new PDO('mysql:host=localhost;dbname=test', 'username', 'password');
$stmt = $pdo->query('SELECT * FROM users WHERE id = 1');
$user = $stmt->fetchObject();
if ($user && isset($user->created_at)) {
$user->created_at = new DateTime($user->created_at);
}
// Now it can be used directly DateTime method
echo $user->created_at->format('YYearmmoondday H:i:s');
?>
Although this method is simple, it has to be converted manually every time . If the table structure is complex or there are many fields, the maintenance cost will increase.
Create an entity class, define the corresponding attribute type, and automatically process the date and time in the constructor.
<?php
class User
{
public int $id;
public string $name;
public DateTime $created_at;
public function __construct()
{
// Need to add the original string created_at Convert to DateTime Object
if (is_string($this->created_at)) {
$this->created_at = new DateTime($this->created_at);
}
}
}
?>
Specify the class name when using fetchObject :
<?php
$pdo = new PDO('mysql:host=localhost;dbname=test', 'username', 'password');
$stmt = $pdo->query('SELECT * FROM users WHERE id = 1');
$user = $stmt->fetchObject(User::class);
echo $user->created_at->format('Y-m-d H:i:s');
?>
The benefits of doing this are:
The code is clearer
Avoid missing field processing
The object structure is more standardized, making it easier for IDE to automatically complete
Suitable for larger projects or long-term maintenance
If your PHP version supports it, you can combine property type declarations , such as constructor property promotion introduced in PHP 8.0, to further simplify the writing of entity classes.
At the same time, make sure that the field format returned by the database always complies with the ISO standard ( YYYY-MM-DD HH:MM:SS ) to avoid DateTime parsing failure.
When using PDOStatement::fetchObject() , the date and time field returned directly is a string. If you need elegant treatment, it is recommended:
Small items can be manually converted to DateTime after removal
In large projects or standardized development, it is highly recommended to use custom entity classes.
By rationally designing entity classes, the robustness and maintainability of the code can be greatly improved.
If you want to know more about PDO usage tips, you can refer to the official documentation .