phpEnv装sqlsrv扩展失败的根本原因是其扩展管理器不识别微软发布的带版本/架构标识的DLL文件名(如php_pdo_sqlsrv_81_nts_x64.dll),需手动复制对应NTS版DLL到phpEnv的ext目录,并在phpEnv根目录php.ini中精确配置完整文件名,同时必须安装ODBC Driver 17 for SQL Server并启用SQL Server TCP/IP协议。

phpEnv 里装 sqlsrv 扩展为什么总失败
因为 phpEnv 自带的扩展管理器根本不识别 sqlsrv/pdo_sqlsrv,它只认 PECL 或 Windows 官方安装包里的标准命名规则,而微软发布的 DLL 文件名带版本号和架构标识(比如 php_pdo_sqlsrv_81_nts_x64.dll),phpEnv 默认加载逻辑会直接跳过。
常见错误现象:PHP Warning: PHP Startup: Unable to load dynamic library 'sqlsrv',或者 Class 'Sqlsrv' not found,但 phpinfo() 里压根不显示 sqlsrv 模块。
- 先确认你的 phpEnv 是 NTS 还是 TS:运行
php -i | grep "Thread Safety",输出disabled表示 NTS(phpEnv 默认) - 查清 PHP 版本:
php -v,比如是PHP 8.1.27 - 去微软 GitHub Releases 页面下载对应包:
pdo_sqlsrv-5.11.1和sqlsrv-5.11.1的Windows x64 non-TS版本 ZIP - 解压后把
php_pdo_sqlsrv_81_nts_x64.dll和php_sqlsrv_81_nts_x64.dll复制到 phpEnv 的ext/目录(不是php/ext/子目录,是 phpEnv 主目录下的 ext) - 编辑 phpEnv 根目录下的
php.ini(不是系统级那个),末尾加两行:extension=php_pdo_sqlsrv_81_nts_x64.dllextension=php_sqlsrv_81_nts_x64.dll
phpEnv 连 SQL Server 必须装 ODBC 驱动
光装扩展没用——sqlsrv 是个“外壳”,底层靠 Windows 系统级 ODBC Driver 通信。phpEnv 不会自动帮你装这个,漏了就会报 Unable to connect: Login failed for user 或更模糊的 Connection refused。
使用场景:本地开发、测试环境、CI/CD 中用 phpEnv 模拟多版本 PHP 时,ODBC 驱动必须由宿主 Windows 系统提供。
立即学习“PHP免费学习笔记(深入)”;
- 下载并安装
ODBC Driver 17 for SQL Server(微软官方最新稳定版,支持 SQL Server 2012+) - 不要装旧版 Driver 11/13,它们不支持 TLS 1.2 强制握手,连 Azure SQL 或新版本地实例会静默失败
- 安装完后,打开 Windows 的
ODBC 数据源(64 位)控制面板,确认列表里有ODBC Driver 17 for SQL Server - 如果 phpEnv 是 32 位 PHP(极少见),还得额外装 32 位驱动;但 phpEnv 默认是 64 位,只装 64 位驱动即可
sqlsrv_connect() 在 phpEnv 下连不上 localhost 的真实原因
不是密码错,也不是扩展没启,而是 SQL Server 默认禁用 TCP/IP 协议,且不监听 127.0.0.1 ——localhost 在 Windows 下会被解析成 127.0.0.1,结果连接直接被拒绝。
性能影响:用实例名(如 DESKTOP-ABCSQLEXPRESS)能绕过 DNS 解析和协议协商,比 IP + 端口略快;但首次连接仍需 SQL Server Browser 服务响应。
- 改用服务器名 + 实例名:
$serverName = "DESKTOP-ABC\SQLEXPRESS";(注意双反斜杠转义) - 或启用 TCP/IP 并指定端口:
$serverName = "DESKTOP-ABC,1433";(前提是 SQL Server 配置管理器里 TCP/IP 已启用) - 连接选项里必须加
"Encrypt" => false,除非你明确配了证书;否则默认开启加密,但本地未配置时会卡住 - 避免用
"TrustServerCertificate" => true,这在生产环境是安全漏洞,仅调试时临时加
pdo_sqlsrv DSN 字符集不生效的坑
在 phpEnv 里用 PDO 连 SQL Server,即使 DSN 写了 CharacterSet=utf8,中文仍可能乱码,原因是微软驱动实际只认 UTF-8(全大写),小写或带中划线都不触发编码转换。
兼容性影响:SQL Server 2019+ 支持 UTF-8 排序规则,但老版本(如 2014)只支持 Chinese_PRC_CI_AS 类排序,此时 CharacterSet 参数无效,得靠字段定义为 nvarchar 并用 N'中文' 前缀插入。
- 正确 DSN 示例:
sqlsrv:Server=DESKTOP-ABC\SQLEXPRESS;Database=testdb;CharacterSet=UTF-8 - 如果连的是 SQL Server 2016 及更早版本,别依赖 CharacterSet,统一用
mb_convert_encoding($str, 'UTF-8', 'GBK')手动转码 - 验证是否生效:执行
SELECT COLLATIONPROPERTY('Chinese_PRC_CI_AS', 'CodePage'),返回936表示 GBK,不是 UTF-8



















