SQL Server 驗證模式說明
| 模式 | 描述 | PHP 連線方式 |
| Windows 驗證 | 使用執行 PHP 進程的 Windows 帳號 | 不指定 UID/PWD,需配置 Apache/IIS 執行身分 |
| SQL Server 驗證 | 資料庫內建帳號密碼 (sa 或自建) | 連線字串指定 UID/PWD (本文重點) |
前置需求
- SQL Server 啟用「混合模式驗證」 (SQL Server Management Studio → 屬性 → 安全性)
- 安裝 Microsoft Drivers for PHP for SQL Server (
php_sqlsrv.dll + php_pdo_sqlsrv.dll)
- 安裝 Microsoft ODBC Driver 17/18 for SQL Server
連線程式碼範例 (sqlsrv 程序式)
<?php
$serverName = "(local)"; // 或 "192.168.1.100,1433"
$uid = 'your_username';
$pwd = 'your_password';
$connectionInfo = [
"UID" => $uid,
"PWD" => $pwd,
"Database" => "AdventureWorks",
"CharacterSet" => "UTF-8", // 重要:避免中文亂碼
"ReturnDatesAsStrings" => true, // 日期回傳字串而非 DateTime 物件
];
$conn = sqlsrv_connect($serverName, $connectionInfo);
if ($conn === false) {
die("連線失敗: " . print_r(sqlsrv_errors(), true));
}
echo "連線成功!";
// 測試查詢
$tsql = "SELECT CONVERT(NVARCHAR(32), SUSER_SNAME()) AS login_user";
$stmt = sqlsrv_query($conn, $tsql);
if ($stmt === false) {
die("查詢失敗: " . print_r(sqlsrv_errors(), true));
}
$row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
echo "目前登入用戶: " . $row['login_user'];
sqlsrv_free_stmt($stmt);
sqlsrv_close($conn);
?>
密碼特殊字元處理
密碼包含右大括號 } 時,連線字串中需雙重轉義:
$pwd = "pass}word"; // 實際密碼
$connInfo["PWD"] = "pass}}word"; // 連線資訊中寫法
PDO_SQLSRV 物件導向寫法 (推薦)
<?php
$dsn = "sqlsrv:Server=(local);Database=AdventureWorks;CharacterSet=UTF-8";
try {
$pdo = new PDO($dsn, $uid, $pwd, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => false,
]);
$stmt = $pdo->query("SELECT SUSER_SNAME() AS login_user");
$row = $stmt->fetch(PDO::FETCH_ASSOC);
echo "登入用戶: " . $row['login_user'];
} catch (PDOException $e) {
die("連線失敗: " . $e->getMessage());
}
?>
常見錯誤排查
| 錯誤訊息 | 可能原因 | 解決方法 |
| Unable to connect to server | 主機名/埠號錯誤、防火牆阻擋 | 檢查 SQL Server 設定管理員 → 網路配置 → TCP/IP 啟用、埠號 1433 |
| Login failed for user | 帳號/密碼錯誤、帳號鎖定、未啟用 SQL 驗證 | SSMS 確認登入帳號狀態、重設密碼、啟用混合模式 |
| Driver not found | php_sqlsrv.dll 未載入、版本不符 (TS/NTS、PHP 版本) | php -m 檢查、下載對應版本 DLL、php.ini 啟用 |
| Character set not supported | ODBC Driver 版本過舊 | 升級 Microsoft ODBC Driver 17/18 |
| 中文亂碼 | 未指定 CharacterSet=UTF-8 | 連線資訊加入 "CharacterSet" => "UTF-8" |
安全性最佳實踐
- 建立專用資料庫帳號,僅授予必要資料庫的
db_datareader/db_datawriter
- 連線字串勿硬編碼,使用環境變數或配置檔 (gitignore)
- 生產環境啟用 TLS 加密連線:
Encrypt=yes;TrustServerCertificate=no
- 定期輪換密碼,審計登入日誌