Db::connect()传数组配置是最稳的多库方案:TP5.1+和6/8均支持运行时创建独立连接,不依赖全局配置,可同时操作MySQL与SQL Server,但需确保驱动启用、type值正确(sqlsrv/mssql)、hostport显式指定,且跨库查询须应用层手动合并。

Db::connect() 传数组配置是最稳的多库方案
ThinkPHP 5.1+ 和 6/8 都支持运行时用 Db::connect() 创建独立数据库连接,这是同时操作 MySQL 和 SQL Server 最可控的方式——不依赖全局配置、不污染默认连接、各连各的,互不影响。
常见错误是直接改 config/database.php 试图塞两个主连接,结果框架只认 default,另一个压根不加载;或者在模型里硬写 $connection 字符串但没配驱动,报 Driver [sqlsrv] not supported。
- 必须确保 PHP 已启用
pdo_sqlsrv或sqlsrv扩展(Windows 下常用,Linux 需装msodbcsql+unixODBC) - MySQL 连接数组用
type => 'mysql',SQL Server 必须用type => 'sqlsrv'(TP6/8)或type => 'mssql'(TP5.1,注意命名差异) - SQL Server 的
hostname建议写 IP(如'192.168.1.100'),避免localhost走命名管道失败 - 端口不能省:SQL Server 默认是
1433,MySQL 是3306,hostport字段必须显式写对
示例(TP8):
$mysql = Db::connect([
'type' => 'mysql',
'hostname' => '127.0.0.1',
'database' => 'shop_db',
'username' => 'root',
'password' => '',
'hostport' => 3306,
]);
<p>$mssql = Db::connect([
'type' => 'sqlsrv',
'hostname' => '192.168.1.100',
'database' => 'crm_db',
'username' => 'sa',
'password' => 'P@ssw0rd',
'hostport' => 1433,
]);
SQL Server 连接失败时优先查扩展和 DSN 格式
报 Class 'PDO' not found 或 Driver not found 不是配置写错了,而是底层没通。TP 只是封装,真正干活的是 PDO 或原生驱动。
立即学习“PHP免费学习笔记(深入)”;
- Windows 下确认
php.ini里开了extension=php_pdo_sqlsrv.dll和extension=php_sqlsrv.dll(注意版本匹配 PHP 线程安全/位数) - Linux 下得装微软官方 ODBC 驱动,再配
pdo_odbc,DSN 得写成odbc:Driver={ODBC Driver 17 for SQL Server};Server=xxx;Database=xxx; - TP6/8 不接受
dsn字符串直接填 SQL Server 地址,必须走数组配置,且type值严格为sqlsrv - 密码含特殊字符(如
@、/)不用 urlencode —— 数组传参不涉及 URL 解析,直接写明文即可
跨库关联查询只能靠应用层拼装
MySQL 和 SQL Server 是不同 DBMS,没有分布式事务支持,也不能写 JOIN 跨库语句。想把 MySQL 的订单和 SQL Server 的客户信息合并展示,必须分两步查,再用 PHP 合并。
- 别在
Db::query()里写SELECT * FROM mysql_db.orders o JOIN sqlsrv_db.customers c ON o.cid = c.id—— 会直接报错或只查一个库 - 先用
$mysql->name('orders')->select()拿订单,再用$mssql->table('customers')->where('id', 'in', $orderCids)->select()拉客户,最后foreach关联 - 如果数据量大,注意内存:SQL Server 查询结果默认是对象,用
toArray()转数组更省空间 - 事务只能单库内保一致性,比如 MySQL 插订单成功但 SQL Server 写日志失败,得自己补救(记录失败 ID、异步重试等)
模型类绑定连接需按 TP 版本区分写法
想让某个模型固定走 SQL Server,不是所有 TP 版本都支持同一写法。TP5.1 和 TP6/8 的模型连接声明方式不同,混用会静默失效。
- TP5.1 模型里写
protected $connection = 'DB_CONFIG_SQLSRV';,前提是你在config.php里定义了这个二级配置名(类似 TP3 风格) - TP6/8 必须用
protected $connection = 'sqlsrv';,且这个sqlsrv要和config/database.php中connections数组的键名完全一致 - TP8 支持在模型里直接写完整数组,但不推荐:
protected $connection = ['type'=>'sqlsrv', 'hostname'=>...]—— 配置分散,难维护 - 一旦模型绑了连接,所有操作(
select、insert、update)都走该库,无法临时切回 MySQL,除非新建实例
最易被忽略的是驱动兼容性:SQL Server 2019+ 默认加密连接,PHP 驱动若太旧会卡在 TLS 握手,此时需在连接数组加 'options' => [PDO::ATTR_EMULATE_PREPARES => true] 降级处理,但代价是预处理失效。



















