Rocky Linux 9+PHP8.1环境下PDO sqlsrv连接SQL Server 2019超时求助
问题:cPanel环境下Rocky 9系统PHP 8.1连接SQL Server 2019出现登录超时错误
在安装了cPanel的Rocky 9 Linux系统上,使用PHP 8.1连接SQL Server 2019时,已按照微软官方文档安装ODBC驱动,尝试多种DSN写法编写连接代码,均出现错误:
SQLSTATE[HYT00]: [Microsoft][ODBC Driver 18 for SQL Server]Login timeout expired
该账号在Microsoft SQL Server Management Studio中可正常连接(本地及远程均可),已排除服务器端防火墙问题,恳请提供解决思路。
连接代码如下:
//config $ip = "xxxxx"; $port = "1433"; $database = "xxxxx"; $user = "xxxxx"; $pass = "xxxxx"; //$dsn = "sqlsrv:Server=$ip,$port;Database=$database;Encrypt=false;TrustServerCertificate=yes"; //tried that to - same effect //$dsn = "sqlsrv:Server='$ip','$port';Database='$database'";//and with brackets - same $dsn = "sqlsrv:Server=$ip,$port;Database=$database;"; $conn = new PDO($dsn, $user, $pass); $conn -> setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
解决思路
- 验证Linux服务器到SQL Server的网络连通性:在Linux服务器上执行
nc -zv [SQL_SERVER_IP] 1433或telnet [SQL_SERVER_IP] 1433,确认能正常建立TCP连接。即使服务器端防火墙已开放,也可能存在Linux本地防火墙、路由跳转或网络运营商限制等问题。 - 明确指定加密相关参数:ODBC Driver 18默认强制启用加密,若SQL Server未配置合法证书,协商过程会导致超时。务必在DSN中添加
Encrypt=false;TrustServerCertificate=yes,确保参数格式正确,示例:$dsn = "sqlsrv:Server=$ip,$port;Database=$database;Encrypt=false;TrustServerCertificate=yes"; - 检查PHP扩展是否正常加载:执行
php -m | grep sqlsrv和php -m | grep pdo_sqlsrv,确认sqlsrv和pdo_sqlsrv扩展已成功加载。也可通过phpinfo()查看扩展的版本信息,确保与ODBC驱动版本兼容。 - 尝试修改Server参数的格式:将DSN中的
Server=$ip,$port改为Server=$ip:$port(冒号分隔IP和端口),部分环境下逗号分隔可能存在解析异常。 - 排查SELinux限制:Rocky 9默认开启SELinux,可能阻止PHP发起外部网络连接。临时执行
setenforce 0关闭SELinux后测试连接,若能成功,再通过setsebool -P httpd_can_network_connect on配置永久规则。 - 启用ODBC追踪日志:修改
/etc/odbcinst.ini文件,添加或修改以下参数,生成详细日志排查具体错误:
执行连接测试后查看日志,定位超时的具体原因。[ODBC] Trace = Yes TraceFile = /var/log/odbc_trace.log - 确认SQL Server TCP/IP协议状态:登录SQL Server配置管理器,检查SQL Server网络配置下的TCP/IP协议是否已启用,且监听端口为1433(需重启SQL Server生效)。部分场景下SSMS通过命名管道连接成功,但TCP/IP未启用会导致PHP连接失败。
- 改用sqlsrv_connect函数测试:编写非PDO的测试代码,排除PDO层的问题,示例:
$serverName = "$ip,$port"; $connectionInfo = array( "Database"=>$database, "UID"=>$user, "PWD"=>$pass, "Encrypt"=>false, "TrustServerCertificate"=>true ); $conn = sqlsrv_connect($serverName, $connectionInfo); if($conn) { echo "连接成功"; } else { die(print_r(sqlsrv_errors(), true)); }
内容的提问来源于stack exchange,提问作者baron_bartek
相关产品推荐
相关产品推荐

