PHP 5.3 起移除舊版 mssql 擴充,官方推薦使用 Microsoft 維護的 sqlsrv / PDO_SQLSRV 驅動,或通用 ODBC 方式。本文詳述三種方案的安裝、設定、連線程式碼與適用場景,並附上常見坑點排查。
.exe (如 SQLSRV5.8.0.exe)。.dll:php_sqlsrv_74_nts_x64.dll、php_pdo_sqlsrv_74_nts_x64.dll 等。.dll 複製到 PHP ext 目錄。php.ini,新增:extension=php_sqlsrv_74_nts_x64.dll
extension=php_pdo_sqlsrv_74_nts_x64.dll
php -m | findstr sqlsrv 確認載入成功。驅動需配合 Microsoft ODBC Driver for SQL Server (建議 17/18 版) 與 SQL Server Native Client (舊版相容) 才能連線。下載 msodbcsql.msi 與 sqlncli.msi 安裝。
<?php
$serverName = '127.0.0.1'; // 或 'localhost,1433'、'(local)\SQLEXPRESS'
$connInfo = [
'UID' => 'sa',
'PWD' => 'your_password',
'Database' => 'master',
'CharacterSet' => 'UTF-8', // 重要:指定編碼
];
$conn = sqlsrv_connect($serverName, $connInfo);
if ($conn === false) {
die(print_r(sqlsrv_errors(), true));
}
echo '連線成功';
// 查詢範例
$sql = 'SELECT * FROM sys.tables';
$stmt = sqlsrv_query($conn, $sql);
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
print_r($row);
}
sqlsrv_free_stmt($stmt);
sqlsrv_close($conn);
?>
<?php
$dsn = 'sqlsrv:Server=127.0.0.1;Database=master;ConnectionPooling=1';
$opt = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
];
try {
$pdo = new PDO($dsn, 'sa', 'your_password', $opt);
$stmt = $pdo->query('SELECT @@VERSION');
echo $stmt->fetchColumn();
} catch (PDOException $e) {
echo '失敗:' . $e->getMessage();
}
?>
適用於 Linux + FreeTDS、或不想安裝專用驅動的環境。
<?php
$dsn = 'odbc:Driver={ODBC Driver 17 for SQL Server};Server=127.0.0.1;Database=master;';
$pdo = new PDO($dsn, 'sa', 'your_password');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $pdo->query('SELECT * FROM sys.tables');
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
print_r($row);
}
?>
Linux 安裝 FreeTDS + unixODBC:
yum install freetds unixODBC php-odbc
# /etc/odbcinst.ini
[FreeTDS]
Driver = /usr/lib64/libtdsodbc.so
Setup = /usr/lib64/libtdsS.so
FileUsage = 1
<?php
$conn = new COM('ADODB.Connection');
$conn->Open("Provider=SQLOLEDB;Data Source=127.0.0.1;Initial Catalog=master;User ID=sa;Password=pass;");
$rs = $conn->Execute('SELECT * FROM sys.tables');
while (!$rs->EOF) {
print_r($rs->Fields['name']->Value);
$rs->MoveNext();
}
$conn->Close();
?>
| 現象 | 原因 | 解決 |
|---|---|---|
| 找不到驅動 / 類別不存在 | dll 版本不符 (TS/NTS、VC版、PHP版) | 用 php -i 確認 Compiler、Thread Safety,下載完全一致的 dll |
| 連線失敗:Login timeout expired | 防火牆阻擋 1433、SQL Server 未啟用 TCP/IP | SQL Server Configuration Manager 啟用 TCP/IP、防火牆開放 1433 |
| 中文亂碼 / ? 亂碼 | 未指定 CharacterSet 或 DB 定序不支援 Unicode | 連線字串加 CharacterSet=UTF-8、欄位用 NVARCHAR |
| PDO::exec 回傳 false 但無例外 | 未設定 ERRMODE_EXCEPTION | 建立 PDO 時加入 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION |
| PHP 版本 | sqlsrv / pdo_sqlsrv 版本 | ODBC Driver 版本 | 支援 SQL Server 版本 |
|---|---|---|---|
| 7.4 | 5.8 / 5.9 | 17 / 18 | 2012 ~ 2022 |
| 8.0 / 8.1 / 8.2 / 8.3 | 5.10 / 5.11 / 5.12 (最新) | 18 (建議) | 2012 ~ 2022 |
新專案首選 PDO_SQLSRV:標準 PDO 介面、支援預處理、參數綁定、交易、錯誤例外,程式碼可攜性最高。舊專案維護可用 sqlsrv 程序式 API。跨平台部署請用 ODBC + FreeTDS。務必安裝對應版本的 ODBC Driver 17/18 並指定 CharacterSet=UTF-8 解決中文編碼問題。