首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 使用 PDO 連接 Access 資料庫:ODBC 驅動配置與最佳實踐

     編輯:PHP 相關知識

PHP 連接 Microsoft Access (.mdb/.accdb) 需透過 ODBC 驅動。PDO_ODBC 提供統一介面,但需正確配置 DSN、驅動版本、架構匹配(32/64 位)。本文提供完整配置步驟、連接代碼、常見錯誤解決。

環境需求

  • Windows Server / Windows 10+ (Linux 需安裝 mdbtools + unixODBC,功能受限)
  • Microsoft Access Database Engine (ACE) 驅動:

關鍵:PHP 進程架構必須與驅動架構一致!

  • 64 位 PHP + 64 位驅動 ✅
  • 32 位 PHP + 32 位驅動 ✅
  • 64 位 PHP + 32 位驅動 ❌ (常見錯誤)

PDO 連接代碼

<?php
/**
 * PDO 連接 Access
 * @param string $dbPath 絕對路徑,如 C:\data\db.mdb 或 /var/www/data/db.accdb
 * @return PDO
 */
function connectAccess(string $dbPath): PDO {
    if (!file_exists($dbPath)) {
        throw new InvalidArgumentException("資料庫檔案不存在:{$dbPath}");
    }

    // 判斷副檔名選擇驅動
    $ext = strtolower(pathinfo($dbPath, PATHINFO_EXTENSION));
    $driver = ($ext === 'accdb') 
        ? 'Microsoft Access Driver (*.mdb, *.accdb)'  // ACE 12.0/16.0
        : 'Microsoft Access Driver (*.mdb)';           // JET 4.0

    $dsn = "odbc:Driver={$driver};Dbq={$dbPath};";

    // 可選參數
    $options = [
        PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::ATTR_EMULATE_PREPARES   => false, // 使用真實預處理
        PDO::ATTR_PERSISTENT         => false, // Access 不支援持久連線
    ];

    try {
        $pdo = new PDO($dsn, '', '', $options); // Access 無帳密
        return $pdo;
    } catch (PDOException $e) {
        // 詳細錯誤診斷
        $msg = $e->getMessage();
        if (str_contains($msg, 'architecture mismatch')) {
            throw new RuntimeException("架構不匹配:PHP 為 " . (PHP_INT_SIZE === 8 ? '64位' : '32位') . ",請安裝對應版本 Access 驅動。原始錯誤:{$msg}");
        }
        if (str_contains($msg, 'driver not found') || str_contains($msg, '未找到驅動程式')) {
            throw new RuntimeException("ODBC 驅動未安裝或名稱錯誤。請確認已安裝 '{$driver}'。原始錯誤:{$msg}");
        }
        throw new RuntimeException("Access 連接失敗:{$msg}");
    }
}

// 使用範例
try {
    $pdo = connectAccess(__DIR__ . '/data.mdb');
    $stmt = $pdo->query('SELECT * FROM users WHERE status = 1');
    $users = $stmt->fetchAll();
    echo "查詢到 " . count($users) . " 筆資料\n";
    print_r($users);
} catch (Throwable $e) {
    echo "錯誤:{$e->getMessage()}\n";
}
?>

ODBC 系統 DSN 配置(可選,較穩定)

  1. 開啟「ODBC 資料來源管理員」(64 位:odbcad32.exe,32 位:C:\Windows\SysWOW64\odbcad32.exe)
  2. 「系統 DSN」頁籤 → 「新增」 → 選擇 Microsoft Access Driver (*.mdb, *.accdb)
  3. 資料來源名稱:MyAccessDB,描述任意
  4. 選擇資料庫檔案路徑 → 確定

PHP 連接:

<?php
$pdo = new PDO('odbc:MyAccessDB', '', '', [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);
?>

常見錯誤與解決

Access 版本驅動下載檔案副檔名
Access 2007-2010Access Database Engine 2010.mdb, .accdb
Access 2013-2016Access Database Engine 2016.accdb
Access 2019/365Access Database Engine 2019/365.accdb
錯誤訊息原因解決
SQLSTATE[IM002] ... Data source name not foundDSN 名稱錯誤、或 32/64 位 ODBC 管理員不匹配確認 PHP 架構、用正確位數 ODBC 管理員建立 DSN、或改用無 DSN 連接字串
architecture mismatch between driver and applicationPHP 64位 + 驅動 32位(或反過來)重新安裝匹配架構的 Access Database Engine。若需共存,用 /passive 參數安裝兩版
Could not find installable ISAM驅動版本過舊不支援 .accdb、或檔案損壞安裝 ACE 12.0+ 驅動、確認檔案完整性
Disk or network error / 無法鎖定檔案檔案被獨佔、權限不足、網路磁碟延遲確保 PHP 執行身分有讀寫權限、關閉其他開啟該檔的程式、本地磁碟優先
Too many fields defined查詢欄位超過 255 個 (Access 限制)縮減 SELECT 欄位、或分表

最佳實踐建議

  1. 避免生產環境用 Access:Access 是桌面資料庫,不支援高併發、無完整事務、易損壞。請遷移至 SQLite / MySQL / PostgreSQL / SQL Server。
  2. 唯讀場景:若僅需讀取匯入,考慮先用工具 (Access、Python pandas、ETL) 匯出 CSV/JSON 再導入目標資料庫。
  3. 連線管理:Access 不支援連線池,每請求新建連線,查詢完立即 $pdo = null 關閉。
  4. 預處理語句:雖 Access 對參數化支援有限,仍建議用 PDO::ATTR_EMULATE_PREPARES => false 並使用 ? 佔位符。
  5. 編碼:Access 內部用 Unicode,PHP 讀取通常無亂碼;若遇中文亂碼,嘗試 PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_UTF8 (需 sqlsrv 驅動) 或在 DSN 加 ;Charset=UTF-8。

Linux 替代方案


# Ubuntu/Debian
sudo apt-get install mdbtools unixodbc unixodbc-dev php-odbc

# 配置 /etc/odbcinst.ini
[MDBTools]
Description=MDBTools Driver
Driver=/usr/lib/x86_64-linux-gnu/odbc/libmdbodbc.so
Setup=/usr/lib/x86_64-linux-gnu/odbc/libmdbodbc.so
FileUsage=1
CPTimeout=5
CPReuse=5

# PHP 連接
$pdo = new PDO("odbc:Driver=MDBTools;Dbq=/path/to/file.mdb;", '', '');

限制:MDBTools 僅支援 .mdb (JET),不支援 .accdb (ACE);效能差、功能不全,僅適合一次性遷移腳本。

總結

PHP PDO 連接 Access 核心在於:架構匹配 (32/64位)、正確驅動名稱、檔案路徑權限。代碼簡單但環境配置易出錯。強烈建議將 Access 作為臨時資料來源,盡快遷移至標準伺服器級資料庫。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved