thinkphp连接sql server需同时满足三条件:正确安装pdo_sqlsrv和sqlsrv扩展(版本、线程模型、位数须与php严格匹配)、系统安装对应位数的microsoft odbc driver、database.php中type设为sqlsrv且hostname推荐用'(local)'或'localhost',缺一则报“驱动未找到”或“无法打开连接”。

ThinkPHP 连接 SQL Server 不是改个 type 就能通的——pdo_sqlsrv 扩展没装对、ODBC 驱动位数不匹配、连接字符串里写 localhost 而不是 (local) 或 127.0.0.1,1433,三者任一出错,都会卡在 “驱动未找到” 或 “无法打开连接”。
pdo_sqlsrv 扩展必须和 PHP 版本、线程模型、系统位数三重对齐
Windows 下常见错误是:下了 php_pdo_sqlsrv_83_ts_x64.dll,但你的 PHP 是 NTS(非线程安全)模式;或用了 x86 DLL,而 PHP 实际是 x64。结果 phpinfo() 里看不到 pdo_sqlsrv 模块,php -m 也搜不到。
- 先用
php -i | findstr "Thread Safety"(Windows)或php -i | grep "Thread Safety"(Linux)确认是enabled(ts)还是disabled(nts) - 再查
Architecture字段,确认是 x64 还是 x86 - 去微软官网下载对应组合的驱动包:
php_pdo_sqlsrv_{PHP_VERSION}_{TS_OR_NTS}_{ARCH}.dll,比如 PHP 8.3 + NTS + x64 →php_pdo_sqlsrv_83_nts_x64.dll - 把两个文件(
php_pdo_sqlsrv_*.dll和php_sqlsrv_*.dll)都放进php/ext,并在php.ini里加两行:extension=php_pdo_sqlsrv_83_nts_x64.dll、extension=php_sqlsrv_83_nts_x64.dll - 重启 Web 服务后,必须打开
phpinfo()页面,手动搜索pdo_sqlsrv和sqlsrv两个关键词——只看有没有,不看“已加载”文字提示
Linux 下缺 ODBC Driver 是硬伤,顺序不能颠倒
pdo_sqlsrv 扩展只是个“翻译官”,它依赖微软的 ODBC Driver for SQL Server 才能真正说话。很多人在 Linux 上装完扩展就去配 TP,结果报 Driver not found: sqlsrv,其实是底层 ODBC 驱动根本没装。
- 安装顺序必须是:
unixODBC(系统级驱动管理器)→msodbcsql(微软 ODBC 驱动)→pdo_sqlsrv(PHP 扩展) - Ubuntu/Debian:运行
sudo apt install unixodbc-dev,再按微软文档装msodbcsql18;CentOS/RHEL 用yum install unixODBC-devel+msodbcsql18 - 验证 ODBC 是否就位:
odbcinst -j看配置路径,sqlcmd -S localhost -U sa -P 'xxx'能连上才说明驱动层通了 - 编译 pdo_sqlsrv 时,
./configure必须带上--with-pdo-sqlsrv=/opt/microsoft/msodbcsql18(路径以你实际安装为准),否则扩展会编译成功但运行时报错
ThinkPHP 的 database.php 里 connection string 写法很关键
TP5/TP8 都用 type => 'sqlsrv',但 hostname 写法不对,照样连不上。SQL Server 对连接字符串解析比 MySQL 严格得多,尤其在本地连接场景。
- Windows 本地测试,推荐用
hostname => '(local)'或'.',而不是'localhost'—— 后者可能走命名管道或 IPv6 回环,不稳定 - 如果指定了端口,必须写成
'127.0.0.1,1433'(逗号分隔,无空格),不能写'127.0.0.1:1433'或'127.0.0.1'+hostport => 1433拆开——TP 的 sqlsrv 驱动不识别这种拆分写法 -
charset => 'utf8'可以设,但实际生效靠 SQL Server 实例的默认排序规则;更稳妥的是在数据库创建时指定COLLATE Chinese_PRC_CI_AS - 如果 SQL Server 启用了 Always Encrypted 或其他高级功能,TP 默认不支持,会直接抛 PDOException,此时得绕过 ORM 直接用
Db::connect()->query()做原生查询
SQL Server 网络协议和防火墙常被忽略
扩展和配置全对,但连不上,90% 是服务端拦住了。SQL Server 默认禁用 TCP/IP,且 Windows 防火墙默认封 1433。
- 进
SQL Server 配置管理器→SQL Server 网络配置→MSSQLSERVER 的协议,把TCP/IP设为“已启用”,右键属性 →IPAll标签页 → 清空TCP 动态端口,填死TCP 端口为1433 - 改完必须重启
SQL Server (MSSQLSERVER)服务,不是 IIS 或 PHP-FPM - Windows 防火墙要放行入站规则:端口 1433,协议 TCP,作用域选“任何位置”或至少“专用”
- 如果是云服务器(如阿里云、腾讯云),安全组也要额外放开 1433 端口——这个坑比本地防火墙还隐蔽
最易被忽略的点是:SQL Server 登录模式必须设为“SQL Server 和 Windows 身份验证模式”,并且 sa 账户要启用、密码强度合规、登录状态为“启用”。哪怕扩展全对、字符串全对、端口全开,只要 sa 被禁用或密码为空,PDO 连接就会静默失败,日志里只显示“Login failed”。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











