當前位置: 首頁> 最新文章列表> 如何在多表查詢中利用PDOStatement::fetchObject 進行字段映射

如何在多表查詢中利用PDOStatement::fetchObject 進行字段映射

gitbox 2025-05-29

在日常開發中,多表聯合查詢(如JOIN )是非常常見的場景。但是如果直接用PDOStatement::fetchObject來獲取結果,很容易遇到(例如不同表有同名字段)的問題。
為了避免這些衝突,並正確地映射到對象屬性,我們可以結合和合理的對象設計,來實現優雅的數據提取。

下面詳細講解實用技巧,並附上示例代碼:

1. 準備數據庫環境

假設我們有兩張表:

 CREATE TABLE users (
    id INT PRIMARY KEY,
    username VARCHAR(50)
);

CREATE TABLE profiles (
    id INT PRIMARY KEY,
    user_id INT,
    bio TEXT
);

2. 建立PHP 類

為了映射多表查詢結果,我們可以創建一個專門的類,比如:

 <?php

class UserProfile
{
    public $user_id;
    public $username;
    public $profile_id;
    public $bio;
}

注意這裡的字段名稱,已經做了區分,例如user_idprofile_id

3. 編寫查詢與字段映射

重點是給查詢的字段設置合適的別名,確保fetchObject 能直接賦值成功。

 <?php

$pdo = new PDO('mysql:host=localhost;dbname=testdb', 'root', 'password');

// 多表聯合查詢,並給字段起別名
$sql = "
SELECT 
    u.id AS user_id, 
    u.username, 
    p.id AS profile_id, 
    p.bio
FROM 
    users u
INNER JOIN 
    profiles p ON u.id = p.user_id
";

$stmt = $pdo->query($sql);

// 直接用 fetchObject 映射成 UserProfile 對象
while ($userProfile = $stmt->fetchObject('UserProfile')) {
    echo "用戶ID: {$userProfile->user_id}\n";
    echo "用戶名: {$userProfile->username}\n";
    echo "簡介: {$userProfile->bio}\n";
    echo "---\n";
}

這樣做的好處是,避免了字段衝突,同時對象結構清晰,便於後續使用,比如傳給前端API 接口或者進行數據處理。

4. 小技巧:動態屬性映射

如果你希望更靈活一點,比如遇到動態結構,可以使用stdClass或者提前準備好的trait,配合映射邏輯。

示例:

 <?php

class DynamicUserProfile
{
    public function __construct(array $data)
    {
        foreach ($data as $key => $value) {
            $this->$key = $value;
        }
    }
}

$stmt = $pdo->query($sql);

while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    $dynamicProfile = new DynamicUserProfile($row);
    echo "用戶名: {$dynamicProfile->username}, 簡介: {$dynamicProfile->bio}\n";
}

雖然這種方式更靈活,但相比fetchObject的原生支持,性能略低,因此要根據實際需求選擇。

5. 注意事項

  • 字段起別名一定要規範,尤其是多表查詢。

  • 對象屬性名要嚴格對應SQL 中的字段別名。

  • 如果是大項目,建議統一寫一個Mapper工具類來自動處理映射細節。

  • 連接外部接口或平台時,比如向https://gitbox.net/api/user/profile這樣的接口發送對像數據,使用清晰的對象結構將極大減少錯誤率。