thinkphp5 连接 sqlserver 必须同时满足:php 已启用 sqlsrv 或 pdo_sqlsrv 扩展,且 database.php 中 type 值严格设为 'sqlsrv';否则报“系统不支持:sqlsrv”。

ThinkPHP5 能连 SQLServer,但必须同时满足两个硬性条件:PHP 环境已启用 sqlsrv 或 pdo_sqlsrv 扩展,且配置中 type 值明确设为 sqlsrv —— 缺一不可,否则必然报“系统不支持:sqlsrv”。
确认 PHP 已加载 sqlsrv 扩展
这是最常卡住的第一步。TP5 报错“系统不支持:sqlsrv”,90% 是因为 PHP 根本没加载对应扩展,而不是 TP 配置错了。
- 运行
php -m | findstr sqlsrv(Windows)或php -m | grep sqlsrv(Linux/macOS),确认输出包含sqlsrv和/或pdo_sqlsrv - 若无输出,需手动安装:Windows 下下载 Microsoft 官方驱动(如
php_pdo_sqlsrv_82_ts.dll),复制到ext/目录,并在php.ini中添加两行:extension=php_pdo_sqlsrv_82_ts.dllextension=php_sqlsrv_82_ts.dll - Linux 用户建议用
pecl install sqlsrv+pecl install pdo_sqlsrv,并确保odbcinst.ini和unixODBC已就位 - 重启 Web 服务(Apache/Nginx)和 CLI 的 PHP 进程,
phpinfo()页面里必须能看到 “sqlsrv” 模块信息
database.php 中正确配置 sqlsrv 连接
TP5 不接受模糊写法,type 必须是字符串 'sqlsrv',且所有关键字段不能省略,否则会静默 fallback 到 mysql 驱动,最终抛出 Class 'PDO' not found 等误导性错误。
- 在
config/database.php的connections数组中定义命名连接,例如:'sqlserver_db' => [ 'type' => 'sqlsrv', 'hostname' => '192.168.1.100', 'database' => 'MyAppDB', 'username' => 'sa', 'password' => 'YourStrongPass!', 'hostport' => '1433', 'charset' => 'utf8', 'prefix' => '', ] -
hostname若为远程地址,注意 SQL Server 默认禁用 TCP/IP,需在 SQL Server Configuration Manager 中启用并重启服务 - 端口不要用冒号写成
192.168.1.100:1433,而应分开填hostname和hostport;实测某些版本对冒号格式解析失败 -
charset设为'utf8'即可,SQL Server 实际使用UTF-16(nvarchar),但 PDO 层自动处理,无需改utf16
代码中调用时只传预定义键名
Db::connect() 只认 config/database.php 里 connections 数组中已声明的键名,传数组、DSN 或拼错名字都会失败,且错误提示极不友好。
- ✅ 正确:
Db::connect('sqlserver_db')->table('users')->select() - ❌ 错误:
Db::connect(['type'=>'sqlsrv', ...])—— 高并发下触发连接耗尽,且绕过连接池 - ❌ 错误:
Db::connect('SQLSERVER_DB')—— 键名大小写敏感,必须全小写 - ❌ 错误:
Db::connect('sqlserver.db')—— 点号会被框架解析器截断,报Connection not found - 首次使用前务必执行
php think clear:config,否则旧缓存可能掩盖配置更新
常见报错与对应检查点
实际部署时,错误往往不是单一原因,而是多个环节叠加失效,需按顺序排查。
-
system not support: sqlsrv→ 检查php -m输出,确认扩展已加载;再确认type值是'sqlsrv'字符串,不是'mssql'或空格 -
SQLSTATE[08001]: [Microsoft][ODBC Driver 17 for SQL Server]Login timeout expired→ 检查防火墙是否放行 1433 端口、SQL Server 是否启用混合认证、用户名密码是否含特殊字符(需 URL 编码或改用配置数组传参) -
SQLSTATE[HY000]: General error: 20018 Invalid object name 'users'→ 表名未加 schema 前缀,SQL Server 默认 schema 是dbo,应写成Db::connect(...)->table('dbo.users')->select() - 查询返回中文乱码 → 不是
charset配置问题,而是 SQL Server 数据库默认排序规则不支持 UTF-8,需确认数据库/表字段为nvarchar类型,并在连接参数中加入:'params' => [\PDO::ATTR_EMULATE_PREPARES => false]
真正麻烦的从来不是配置几行代码,而是环境层的扩展缺失、SQL Server 服务配置、网络策略三者咬合不上——一旦报错,优先抓 phpinfo() 截图和 telnet 192.168.x.x 1433 结果,比反复改 PHP 配置有用得多。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











