不能直接连接,PHP 7.3 原生不支持 SQL Server,必须安装匹配版本的微软 sqlsrv 和 pdo_sqlsrv 扩展(最低 v5.8.0),并配置 ODBC 驱动(如 ODBC Driver 17),同时确保 PHP 线程安全模式、架构(x64/x86)与扩展一致,且 SQL Server 启用 TCP/IP 并开放端口。

PHP7.3能否直接连接SQL Server 2019?
不能直接连——PHP7.3原生不带sqlsrv扩展,必须手动安装微软官方驱动sqlsrv和pdo_sqlsrv扩展,且版本必须匹配。SQL Server 2019要求驱动最低为5.8.0(对应PHP7.3),低于该版本会报Connection failed: SQLSTATE[08001]或Unable to connect...这类错误。
如何安装兼容PHP7.3的sqlsrv扩展?
Windows下最稳妥的方式是下载微软预编译DLL,Linux需编译源码(但PHP7.3在2023年后已停止安全更新,Ubuntu/Debian官方仓库通常不再提供适配包,容易卡在unixODBC或msodbcsql17依赖上)。
- 确认PHP线程安全模式:
php -i | findstr "Thread Safety"(Windows)或php -i | grep "Thread Safety"(Linux),结果为enabled则用TS版DLL,disabled用NTS版 - 下载地址:微软官网
Microsoft Drivers for PHP for SQL Serverv5.8.0(支持PHP7.2–7.4),注意选对架构(x64/x86)和TS/NTS - Windows:把
php_sqlsrv_73_ts.dll和php_pdo_sqlsrv_73_ts.dll放入ext/目录,在php.ini里加两行:extension=php_sqlsrv_73_ts.dll和extension=php_pdo_sqlsrv_73_ts.dll - Linux(Ubuntu 18.04+):先装
msodbcsql17和unixodbc-dev,再用pecl install sqlsrv(需指定phpize路径),否则pdo_sqlsrv可能加载失败
连接字符串写法与常见报错
用sqlsrv_connect()或PDO都行,但PDO更易调试;SQL Server 2019默认禁用TCP/IP远程连接,且Windows认证(Windows Auth)在PHP里基本不可用,必须用SQL Server认证(用户名密码)。
- 基础连接示例(PDO):
$conn = new PDO("sqlsrv:server=localhost;Database=testdb", "sa", "YourStrong@Passw0rd"); - 若报
SQLSTATE[HYT00]: [Microsoft][ODBC Driver 17 for SQL Server]Login timeout expired,先检查SQL Server是否启用TCP/IP协议(SQL Server Configuration Manager → 协议 → TCP/IP → 启用),并确认sqlservr.exe监听端口(默认1433)没被防火墙拦截 - 若报
SQLSTATE[08001]: [Microsoft][ODBC Driver 17 for SQL Server]Named Pipes Provider: Could not open a connection...,说明连接字符串用了localhost但SQL Server只允许命名管道——改用127.0.0.1或具体IP - 字符集问题:SQL Server 2019默认用
UTF-8排序规则,但PHP驱动仍按UTF-16传数据,中文字段可能乱码;可在连接后执行SET NAMES utf8(不生效),正确做法是在DSN里加;CharacterSet=utf8(仅sqlsrv扩展支持,PDO不认)
PHP7.3 + SQL Server 2019实际可用性提醒
PHP7.3已于2021年12月停止所有支持,SQL Server 2019最新CU补丁(如CU21)已不再验证与PHP7.3的兼容性。生产环境遇到Segmentation fault或查询返回空数组但无错误时,大概率是驱动版本与PHP运行时ABI不匹配,而非代码问题。
立即学习“PHP免费学习笔记(深入)”;
真正麻烦的是:SQL Server 2019新增的STRING_AGG、JSON_VALUE等函数,PHP7.3的sqlsrv扩展v5.8.0虽能执行,但返回结果类型处理有缺陷(比如JSON_VALUE返回string而非object),得靠json_decode()二次转换——这点很容易被忽略,直到前端渲染出错才意识到。



















