PHP ODBC

Reaching non-MySQL sources via ODBC: DSN setup, odbc_* functions, and PDO_ODBC.

Intermediate
Key PointsODBC is a database-agnostic middle layer; the DSN holds driver, address and credentials.

When to use ODBC

  • SQL Server, Oracle, DB2, Access —— when PDO lacks a driver
  • Vendor data sources —— ERP and accounting systems often expose ODBC
  • Cross-database joins —— some drivers support it

Prefer native drivers (pdo_sqlsrv, oci8). ODBC is the fallback when nothing better exists — usually slower and weaker on multibyte.

Configuring a DSN

Two flavours: a system DSN in /etc/odbc.ini or the Windows registry, and DSN-less connection strings.

INI
; /etc/odbc.ini
[mydb]
Driver   = /usr/lib/x86_64-linux-gnu/odbc/libsqlite3odbc.so
Database = /var/data/app.db
PHP
<?php
// 有 DSN
$conn = odbc_connect("mydb", "user", "pass");

// 无 DSN:直接把驱动和参数拼进连接串
$dsnless = "Driver={SQL Server};Server=127.0.0.1;Database=demo;";
// $conn = odbc_connect($dsnless, "sa", "secret");

echo $conn === false ? "连接失败: " . odbc_errormsg() : "连接成功", "\n";
Output
连接成功

Running queries

PHP
<?php
$conn = odbc_connect("mydb", "user", "pass");
if ($conn === false) {
    exit("连接失败: " . odbc_errormsg());
}

$res = odbc_exec($conn, "SELECT id, name FROM users ORDER BY id");
if ($res === false) {
    exit("查询失败: " . odbc_errormsg($conn));
}

while ($row = odbc_fetch_array($res)) {
    echo $row["id"] . " " . $row["name"] . "\n";
}

odbc_free_result($res);
odbc_close($conn);
Output
1 Tom
2 Amy
3 Bob
Key case depends on the driver — SQL Server may return NAME. Normalise with array_change_key_case or fetch by index.

Parameterised queries

PHP
<?php
$conn = odbc_connect("mydb", "user", "pass");

$sql = "SELECT name FROM users WHERE id = ?";
$prep = odbc_prepare($conn, $sql);

if ($prep === false) {
    exit("预处理失败: " . odbc_errormsg($conn));
}

odbc_execute($prep, [1]);

while ($row = odbc_fetch_array($prep)) {
    echo $row["name"] . "\n";
}
Output
Tom

odbc_prepare with odbc_execute supports positional ?. **Never concatenate into odbc_exec** — as dangerous as the old mysql_query.

Using PDO_ODBC

Prefer PDO's interface? The pdo_odbc driver behaves like any other.

PHP
<?php
$pdo = new PDO("odbc:mydb", "user", "pass", [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);

$stmt = $pdo->prepare("SELECT name FROM users WHERE id = ?");
$stmt->execute([2]);
echo $stmt->fetchColumn(), "\n";
Output
Amy

Common issues

SymptomCauseFix
[IM002] Data source name not foundDSN 没配或名字拼错查 odbcinst -q -d、odbc.ini 路径
[IM003] Specified driver could not be loaded驱动 .so 路径错或缺依赖ldd 查缺的库
[28000] Login failed认证失败查账号、认证模式(SQL / Windows)
中文乱码客户端字符集与库不一致连接串里指定字符集,或 SET NAMES
odbc_exec 返回 false 但无错误没开 odbc.defaultlrl 或超时odbc_errormsg() 看详情
Linux has system and per-user odbc.ini with the user one winning. When a DSN seems missing, check the paths reported by odbcinst -j.

Friends & Partners