在使用PHP 的PDO 操作數據庫時, PDOStatement::fetchObject()方法非常方便,它可以將查詢結果直接映射為一個對象。然而,當數據庫字段中包含(如DATETIME 、 TIMESTAMP類型)時,直接使用fetchObject可能會遇到一些問題,比如日期字段被當作普通字符串處理,導致後續格式化和比較變得麻煩。
本文將講解如何在使用fetchObject時,正確地處理這些日期時間字段,並給出實用示例。
假設有一個用戶表users ,結構如下:
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
created_at DATETIME NOT NULL
);
插入一條數據:
INSERT INTO users (name, created_at) VALUES ('Alice', '2025-04-27 14:30:00');
用fetchObject獲取數據:
<?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;
?>
輸出的是一段普通字符串:
2025-04-27 14:30:00
如果想要對created_at進行時間加減、格式化等操作,就不得不手動用DateTime類轉換,非常不優雅。
有兩種常見方式來優雅地處理:
在拿到對像後,立即將日期字段轉成DateTime對象。
<?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);
}
// 現在可以直接使用 DateTime 方法
echo $user->created_at->format('Y年m月d天 H:i:s');
?>
雖然這種方式簡單,但每次都要手動轉換,如果表結構複雜或者字段多,維護成本會增加。
創建一個實體類,定義好對應的屬性類型,並在構造函數中自動處理日期時間。
<?php
class User
{
public int $id;
public string $name;
public DateTime $created_at;
public function __construct()
{
// 需要將原本的字符串 created_at 轉成 DateTime 對象
if (is_string($this->created_at)) {
$this->created_at = new DateTime($this->created_at);
}
}
}
?>
使用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');
?>
這樣做的好處是:
代碼更清晰
避免遺漏字段處理
對象結構更規範,方便IDE 自動補全
適合更大型的項目或長期維護
如果你的PHP 版本支持,可以結合屬性類型聲明,例如PHP 8.0 引入的constructor property promotion,進一步簡化實體類寫法。
同時,確保數據庫返回的字段格式始終符合ISO 標準( YYYY-MM-DD HH:MM:SS ),以免DateTime解析失敗。
使用PDOStatement::fetchObject()時,直接返回的日期時間字段是字符串。如果需要優雅處理,建議:
小項目可在取出後手動轉換為DateTime
大項目或規範開發中,強烈推薦使用自定義實體類
通過合理設計實體類,可以極大提升代碼的健壯性和可維護性。
如果你想了解更多關於PDO 使用技巧,可以參考官方文檔。