# SQLSTATE[08001]：[Microsoft][ODBC Driver 17 for SQL Server]TCP 提供程序：错误代码 0x2746

- **ID:** `php/pdo-sqlsrv-connection-failure`
- **领域:** php
- **类别:** network_error
- **错误码:** `08001`
- **验证级别:** ai_generated
- **修复率:** 82%

## 根因

PHP PDO_SQLSRV 连接失败，原因是客户端 ODBC 驱动与 SQL Server 之间的 TLS 协议不匹配，常见于 SQL Server 禁用了较旧的 TLS 版本（如 TLS 1.0/1.1）或客户端缺少所需的密码套件。

## 版本兼容性

| 版本 | 状态 | 引入 | 弃用 |
|------|------|------|------|
| 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 | — | — |

## 解决方案

1. ```
   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);`
   ```
2. ```
   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** — The default ODBC driver installation may still use outdated TLS configurations; reinstalling alone does not change the TLS protocol negotiation behavior. (70% 失败率)
- **Downgrading PHP to an older version (e.g., 7.4)** — 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. (90% 失败率)
