ODBC (Open Database Connectivity) 提供統一介面存取不同資料庫 (MySQL、PostgreSQL、SQL Server、Access 等)。本文示範 PHP odbc_* 函數族連接 MySQL 的完整流程:DSN 設定、連線、查詢、結果遍歷、關閉連線、錯誤處理,並說明免 DSN 連接字串寫法。
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<title>PHP ODBC 連線測試</title>
</head>
<body>
<?php
// 1. 連接字串 (免 DSN,直接指定驅動程式)
$connStr = "DRIVER={MySQL ODBC 8.0 Unicode Driver};Server=127.0.0.1;Port=3306;Database=testdb;Charset=utf8mb4;";
$username = 'dbuser';
$password = 'dbpass';
echo '<h3>嘗試連接...</h3>';
// 2. 建立連線
$conn = odbc_connect($connStr, $username, $password);
if (!$conn) {
echo '<p style="color:red;">連線失敗: </p>';
echo '<pre>' . htmlspecialchars(odbc_errormsg()) . '</pre>';
exit;
}
echo '<p style="color:green;">連線成功!</p>';
// 3. 執行查詢
$sql = "SELECT 1 AS test_value, 'Hello ODBC' AS message";
$result = odbc_exec($conn, $sql);
if (!$result) {
echo '<p style="color:red;">查詢失敗: </p>';
echo '<pre>' . htmlspecialchars(odbc_errormsg($conn)) . '</pre>';
odbc_close($conn);
exit;
}
// 4. 輸出結果表格
echo '<table border="1" cellpadding="6" cellspacing="0">';
echo '<tr><th>test_value</th><th>message</th></tr>';
while (odbc_fetch_row($result)) {
$val1 = odbc_result($result, 'test_value');
$val2 = odbc_result($result, 'message');
echo "<tr><td>{$val1}</td><td>{$val2}</td></tr>";
}
echo '</table>';
// 5. 釋放資源並關閉
odbc_free_result($result);
odbc_close($conn);
echo '<p>連線已關閉。</p>';
?>
</body>
</html>
| 函數 | 用途 | 備註 |
|---|---|---|
odbc_connect($dsn, $user, $pass) | 建立連線 | 支援 DSN 名稱或完整連接字串 |
odbc_pconnect() | 持久連線 | 跨請求重用,需注意連線數上限 |
odbc_exec($conn, $sql) | 執行 SQL 回傳結果集 | 僅適用 SELECT/SHOW 等有結果集的語句 |
odbc_prepare() / odbc_execute() | 預備語句 (參數化) | 防 SQL 注入、重複執行效能佳 |
odbc_fetch_row($result) | 移動至下一列 | 回傳 bool,配合 while 迴圈 |
odbc_result($result, $field) | 取得欄位值 | 支援欄位名或 1-based 索引 |
odbc_fetch_array() | 取得關聯+數值陣列 | PHP 4.3+,更方便 |
odbc_num_rows() | 取得列數 | 某些驅動不支援 (回傳 -1) |
odbc_error() / odbc_errormsg() | 取得錯誤代碼/訊息 | 連線失敗用無參數,查詢失敗傳 $conn |
odbc_close($conn) | 關閉連線 | 持久連線實際不關閉,歸還池中 |
# MySQL (需安裝 MySQL ODBC Driver)
DRIVER={MySQL ODBC 8.0 Unicode Driver};Server=host;Port=3306;Database=db;Charset=utf8mb4;UID=user;PWD=pass;
# PostgreSQL
DRIVER={PostgreSQL Unicode};Server=host;Port=5432;Database=db;UID=user;PWD=pass;
# SQL Server (Microsoft ODBC Driver 17/18)
DRIVER={ODBC Driver 18 for SQL Server};Server=tcp:host,1433;Database=db;UID=user;PWD=pass;Encrypt=yes;TrustServerCertificate=no;
# Microsoft Access (.accdb)
DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=C:\path\file.accdb;
# Oracle
DRIVER={Oracle in OraClient12Home1};DBQ=host:1521/sid;UID=user;PWD=pass;
yum install unixODBC unixODBC-devel 或 apt install unixodbc unixodbc-dev。.tar.gz 解壓,執行 ./install.sh 或手動複製 libmyodbc8w.so 至 /usr/lib64/,註冊 odbcinst.ini。odbcinst -q -d -n "MySQL ODBC 8.0 Unicode Driver"。docker-php-ext-install odbc 或 yum install php-odbc / apt install php-odbc。php -m | grep odbc 確認載入。| 場景 | 推薦 | 理由 |
|---|---|---|
| 僅連接 MySQL/MariaDB | PDO_MySQL / mysqli | 效能最佳、功能完整、社群支援最好 |
| 需連接多種異構資料庫 | ODBC / PDO_ODBC | 單一介面、統一程式碼、驅動層隔離差異 |
| 舊系統遷移 (Access/Excel/舊 ERP) | ODBC | 無原生驅動時的唯一選擇 |
| Windows 環境連接 SQL Server | PDO_SQLSRV / sqlsrv | 微軟官方驅動,效能優於 ODBC |
ODBC 是跨資料庫整合的標準橋樑,掌握其連線字串組裝與錯誤處理,能在異構系統整合專案中發揮關鍵作用。