SQLSTATE[08001]:[Microsoft][ODBC Driver 17 for SQL Server]TCP 提供程序:错误代码 0x2746
SQLSTATE[08001]: [Microsoft][ODBC Driver 17 for SQL Server]TCP Provider: Error code 0x2746
ID: php/pdo-sqlsrv-connection-failure
版本兼容性
| 版本 | 状态 | 引入 | 弃用 | 备注 |
|---|---|---|---|---|
| php 8.1 | active | — | — | — |
| php 8.2 | active | — | — | — |
| php 8.3 | active | — | — | — |
| ODBC Driver 17 for SQL Server | active | — | — | — |
| ODBC Driver 18 for SQL Server | active | — | — | — |
根因分析
PHP PDO_SQLSRV 连接失败,原因是客户端 ODBC 驱动与 SQL Server 之间的 TLS 协议不匹配,常见于 SQL Server 禁用了较旧的 TLS 版本(如 TLS 1.0/1.1)或客户端缺少所需的密码套件。
English
The PHP PDO_SQLSRV connection fails due to TLS protocol mismatch between the client ODBC driver and the SQL Server, often after SQL Server disables older TLS versions (e.g., TLS 1.0/1.1) or the client lacks a required cipher suite.
官方文档
https://learn.microsoft.com/en-us/sql/connect/odbc/download-odbc-driver-for-sql-server解决方案
-
Update the ODBC driver to version 18 and configure TLS settings in the connection string: `$conn = new PDO('sqlsrv:Server=host;Database=db;Encrypt=yes;TrustServerCertificate=yes;LoginTimeout=30;', $user, $pass);` -
Add `'CryptoProtocolVersion' => 'TLSv1.2'` to the connection string or set the environment variable `ODBCSYSINI` to point to a custom `odbc.ini` with `CryptoProtocolVersion=TLSv1.2`.
无效尝试
常见但无效的做法:
-
Reinstalling the ODBC driver without updating TLS settings
70% 失败
The default ODBC driver installation may still use outdated TLS configurations; reinstalling alone does not change the TLS protocol negotiation behavior.
-
Downgrading PHP to an older version (e.g., 7.4)
90% 失败
The TLS handshake failure is not a PHP version issue but a driver-level configuration problem; downgrading PHP does not alter the ODBC driver's TLS behavior.