在 Windows 環境下,PHP 可透過 COM 元件呼叫 ADO (ActiveX Data Objects) 連接 Microsoft Access (.mdb/.accdb) 資料庫,無需安裝 ODBC 驅動程式即可操作。本文詳細說明 COM 連接架構、程式碼實作、常見錯誤排查與現代替代方案。
PHP Script
│
▼
COM Extension (php_com_dotnet.dll)
│
▼
ADODB.Connection (COM 物件)
│
▼
Microsoft Access Driver (*.mdb, *.accdb) ← Windows 內建 ODBC 驅動
│
▼
Access 資料庫檔案 (.mdb / .accdb)
<?php
// 1. 建立 COM 連線物件
try {
$conn = new COM("ADODB.Connection") or die("無法建立 ADODB.Connection COM 物件");
} catch (com_exception $e) {
die("COM 初始化失敗: " . $e->getMessage());
}
// 2. 連線字串 (DSN-less)
$dbPath = realpath(__DIR__ . '/data/member.mdb'); // 建議使用絕對路徑
if (!$dbPath || !file_exists($dbPath)) {
die("資料庫檔案不存在: {$dbPath}");
}
// Access 2000-2003 (.mdb)
$dsn = "Driver={Microsoft Access Driver (*.mdb)};Dbq={$dbPath};";
// Access 2007+ (.accdb) 需安裝 ACE 驅動
// $dsn = "Driver={Microsoft Access Driver (*.mdb, *.accdb)};Dbq={$dbPath};";
try {
$conn->Open($dsn);
} catch (com_exception $e) {
die("資料庫連線失敗: " . $e->getMessage() . "
DSN: {$dsn}");
}
// 3. 執行查詢
$sql = "SELECT UserName, PassWord, Email FROM Users WHERE Active = 1";
$rs = $conn->Execute($sql);
// 4. 遍歷記錄集
if ($rs && !$rs->EOF) {
echo "<table border='1' cellpadding='5'>";
echo "<tr><th>使用者</th><th>密碼</th><th>Email</th></tr>";
while (!$rs->EOF) {
// COM 物件屬性存取:$rs->Fields['欄位名']->Value
$user = $rs->Fields['UserName']->Value ?? '';
$pass = $rs->Fields['PassWord']->Value ?? '';
$email = $rs->Fields['Email']->Value ?? '';
echo "<tr><td>{$user}</td><td>{$pass}</td><td>{$email}</td></tr>";
$rs->MoveNext();
}
echo "</table>";
} else {
echo "查無資料";
}
// 5. 清理資源
$rs->Close();
$rs = null;
$conn->Close();
$conn = null;
?>
| 項目 | 說明 |
|---|---|
php_com_dotnet.dll | PHP 7.4+ 需在 php.ini 啟用 extension=com_dotnet (Windows 專用) |
| DSN-less 連線 | 無需在 ODBC 管理員建立系統 DSN,直接在連線字串指定驅動與檔案路徑 |
| 驅動名稱 | {Microsoft Access Driver (*.mdb)} 為 .mdb;{Microsoft Access Driver (*.mdb, *.accdb)} 需另裝 Access Database Engine (ACE) |
| 記錄集游標 | 預設為前進唯讀,若需移動記錄指標可指定 $conn->Open($dsn, '', '', adOpenStatic) 需引入 adovbs.inc 常數定義 |
| 欄位值存取 | $rs->Fields['欄位名']->Value 或 $rs->Fields(索引)->Value (0-based) |
| 錯誤處理 | 捕獲 com_exception,檢查 $e->getCode() (HRESULT) 與 $e->getMessage() |
extension=com_dotnet,重啟 Web 伺服器。iconv('CP950', 'UTF-8', $value)。COM 方式綁定 Windows 平台且除錯困難。建議改用標準 PDO 抽象層:
<?php
// PDO + ODBC (需安裝 php_pdo_odbc + Access ODBC 驅動)
$dsn = "odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)};Dbq=" . realpath('data/member.accdb');
$pdo = new PDO($dsn, '', '', [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
$stmt = $pdo->query("SELECT UserName, PassWord FROM Users");
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo "{$row['UserName']} - {$row['PassWord']}
";
}
// 或 PDO_SQLSRV 連接 SQL Server LocalDB (Access 遷移首選)
$pdo = new PDO("sqlsrv:Server=(localdb)\\MSSQLLocalDB;Database=MyDB", '', '');
?>
PHP COM 連接 Access 是 Windows 平台特有的輕量級方案,適合舊系統維護、小型內部工具、單機桌面應用。新專案強烈建議採用 PDO + ODBC 或遷移至客戶端-伺服器架構資料庫 (MySQL/PostgreSQL/SQL Server),獲得跨平台、高併發、標準化的資料存取能力。