SQL Server连接需装扩展、配驱动、改配置三步全对才通,缺一不可;常见卡点包括Windows下TS/NTS驱动不匹配、Linux下未装unixodbc/msodbcsql18、PHP配置中type误设为pdo_sqlsrv或含dsn字段、未启用TCP/IP协议及防火墙拦截1433端口。

能连,但不是开箱即用——必须装扩展、配驱动、改配置三步全对才通。缺一不可,尤其容易卡在驱动版本和 PHP 线程模型不匹配上。
sqlsrv 扩展装不对,phpinfo 里根本看不到 sqlsrv
Windows 下常见问题:下载了 php_sqlsrv_80_ts.dll,但你的 PHP 是 NTS(非线程安全)版;或者反过来。打开 phpinfo(),搜 Thread Safety,明确看到是 enabled(TS)还是 disabled(NTS)。再核对 DLL 文件名里的 ts 或 nts 标识是否一致。
Linux(如 Ubuntu 24.04)更麻烦:不能只装 sqlsrv.so,必须先装 unixodbc 和 odbcinst,再装 msodbcsql18,否则 pdo_sqlsrv 加载会静默失败。
- 先运行
apt install -y unixodbc odbcinst - 再用
dpkg -i msodbcsql18.deb安装驱动 - 最后验证:
odbcinst -j看配置路径,odbcinst -j -d看驱动列表是否含[ODBC Driver 18 for SQL Server]
database.php 里 type=sqlsrv,但连不上还报 HY000 错误
错误信息 SQLSTATE[HY000] [1045] Access denied for user 'xxx'@'localhost' 看似像 MySQL 权限错,其实是 ThinkPHP 没识别到 sqlsrv 驱动,fallback 到了默认的 MySQL 连接器。本质是 type 配置没生效,或扩展根本没加载成功。
立即学习“PHP免费学习笔记(深入)”;
真正有效的 SQL Server 配置长这样:
return [
'connections' => [
'sqlsrv' => [
'type' => 'sqlsrv',
'hostname' => '192.168.1.100',
'hostport' => '1433',
'database' => 'mydb',
'username' => 'sa',
'password' => 'YourPass!2026',
'charset' => 'utf8',
'prefix' => '',
'params' => [],
],
],
];
注意三点:
-
type必须是sqlsrv,不是pdo_sqlsrv或odbc -
hostport显式写1433,别依赖默认值(TP6 不自动 fallback) - 不要加
dsn字段——除非你明确走pdo_odbc,否则 TP6 的sqlsrv类型不认它
连接成功了,但中文乱码或 datetime 字段报错
SQL Server 默认用 Chinese_PRC_CI_AS 排序规则,而 PHP 扩展默认传参用 UTF-8 编码,中间没做转换,查出来就是乱码;插入带毫秒的 datetime2 也可能被截断或报类型不匹配。
解决方案不是改数据库排序规则(风险大),而是让驱动层处理:
- 在
params数组里加:'CharacterSet' => 'UTF-8' - 如果字段是
datetime2,查询时显式 cast:Db::connect('sqlsrv')->query("SELECT CAST(created_at AS DATETIME) FROM table") - 避免用
->where('name', '张三')直接传中文条件,改用参数绑定:->where('name', '=', ':name')->bind(['name' => '张三'])
想连 SQL Server 2000 这种老库,sqlsrv 扩展直接报不支持
微软官方驱动最低只支持 SQL Server 2005,SQL Server 2000 必须绕道 pdo_odbc。这时不能用 type="sqlsrv",得切回 PDO 路线:
'sqlserver2000' => [
'type' => 'pdo',
'dsn' => 'odbc:Driver={SQL Server};Server=127.0.0.1,1433;Database=mydb;',
'username' => 'sa',
'password' => 'xxx',
],
关键点:
- Windows 下用系统自带的
{SQL Server}驱动(控制面板 → 管理工具 → ODBC 数据源 → 驱动程序页能看到) - Linux 下需安装
unixODBC+freeTDS,并手动配置/etc/odbc.ini和/etc/freetds.conf - TP6 的
pdo类型不会自动加载pdo_odbc扩展,要确认php.ini里有extension=pdo_odbc
最常被跳过的一步:SQL Server 实例本身没开 TCP/IP 协议,或者 Windows 防火墙拦了 1433 端口。哪怕 PHP 和驱动全对,连过去也是超时。务必进 SQL Server 配置管理器里把 TCP/IP 启用,并检查 IPAll 的 TCP 端口设为 1433 且 TCP 动态端口清空。



















