1

通过以下连接尝试,我收到“登录超时已过期”:

$dbx = new PDO("sqlsrv:Server=RemoteSQLServer;Database=TheDatabase", SQL_USER, SQL_PW);

如果我添加登录超时:

$dbx = new PDO("sqlsrv:Server=RemoteSQLServer;Database=TheDatabase;LoginTimeout=60;", SQL_USER, SQL_PW);

该脚本返回一个 Bad Gateway 错误。我不知所措,不确定我错过了什么。详情如下。

这是一个安装了 PHP 7.4.6 的 RHEL 8.3 系统。RemoteSQLServer 是一个运行 SQLServer 2012 的远程 Windows 系统。我能够使用 php-mssql 从 RHEL 7 系统成功连接到这个实例(据我所知,这在 RHEL 8 中不可用)。

为了希望排除任何网络问题,我可以使用tsqlRHEL 8 客户端连接到 RemoteSQLServer,而且问题为零。

[user@rhel8client ~]# tsql -S RemoteSQLServer -U SQL_USER
Password: 
locale is "en_US.UTF-8"
locale charset is "UTF-8"
using default charset "UTF-8"
1> select getdate();
2> go

Apr 19 2021 08:32:06:467PM
(1 row affected)
1> quit
[user@rhel8client ~]# 

相关phpinfo详细信息:

[user@rhel8client ~]# php -i | grep sqlsrv
/etc/php.d/20-sqlsrv.ini,
/etc/php.d/30-pdo_sqlsrv.ini,
/etc/php.d/30-sqlsrv.ini,
Registered PHP Streams => https, ftps, compress.zlib, php, file, glob, data, http, ftp, compress.bzip2, phar, sqlsrv
PDO drivers => mysql, sqlite, sqlsrv
pdo_sqlsrv
pdo_sqlsrv support => enabled
pdo_sqlsrv.client_buffer_max_kb_size => 10240 => 10240
pdo_sqlsrv.log_severity => 0 => 0
pdo_sqlsrv.report_additional_errors => 1 => 1
pdo_sqlsrv.set_locale_info => 2 => 2
sqlsrv
sqlsrv support => enabled
sqlsrv.ClientBufferMaxKBSize => 10240 => 10240
sqlsrv.LogSeverity => 0 => 0
sqlsrv.LogSubsystems => 0 => 0
sqlsrv.SetLocaleInfo => 2 => 2
sqlsrv.WarningsReturnAsErrors => On => On

上面的ini文件:

[user@rhel8client ~]# cat /etc/php.d/20-sqlsrv.ini
extension=sqlsrv.so

[user@rhel8client ~]# cat /etc/php.d/30-sqlsrv.ini
extension=sqlsrv.so

[user@rhel8client ~]# cat /etc/php.d/30-pdo_sqlsrv.ini
extension=sqlsrv.so

相关安装包:

[user@rhel8client ~]# yum list installed | grep msodb
msodbcsql17.x86_64                            17.7.2.1-1                               @System   

[user@rhel8client ~]# yum list installed | grep ODBC
unixODBC.x86_64                               2.3.7-1.el8                              @rhel-8-for-x86_64-appstream-rpms        
unixODBC-devel.x86_64                         2.3.7-1.el8                              @rhel-8-for-x86_64-appstream-rpms 

[user@rhel8client ~]# pecl list
Installed packages, channel pecl.php.net:
=========================================
Package    Version State
pdo_sqlsrv 5.9.0   stable
sqlsrv     5.9.0   stable

这篇2019 年的帖子提出了一个类似的问题,但唯一的答案似乎遗漏了安装他们列出的软件包后要做什么的详细信息(我已经做了很多,见上文)。

我不确定我还需要在这里做什么。

有没有办法让 PDO 使用 tsql?

4

1 回答 1

0

我终于想出了如何从 RHEL8 机器到运行 SQL Server 2012 的 Windows 系统建立有效连接。这个方法很有帮助。

首先安装几个需要的包

sudo dnf install php-odbc freetds freetds-devel

转到您的 SQL Server 2012 机器并获取这些变量:

SELECT @@servername AS 'Server Name'; # MYSERVERNAME
SELECT @@servicename AS 'Instance Name'; # MSSQLSERVER

从提示发出此命令以获取libtdsodbc.so.0路径

ldconfig -p | grep libtdsodbc

[user@rhel8 ~]# ldconfig -p | grep libtdsodbc
->  libtdsodbc.so.0 (libc6,x86-64) => /lib64/libtdsodbc.so.0
    libtdsodbc.so (libc6,x86-64) => /lib64/libtdsodbc.so

编辑/etc/odbcinst.ini该部分并将其更改FreeTDS为以下内容:

[FreeTDS]
Description = FreeTDS Driver
Driver = /lib64/libtdsodbc.so.0
# save & exit

编辑/etc/odbc.ini——这个 ini 文件定义了 DSN。注意开头可能是空白的,没关系

[ArbitraryServerID]
Description = AppDatabase database on MYSERVERNAME
Driver = FreeTDS
Database = AppDatabase
ServerName = ArbitraryServerID
TDS_Version = 8.0
# save and exit

注意:“ArbitraryServerID”可以是任何字符串 - 只需在所有配置中一致地使用它

编辑/etc/freetds.conf以添加以下部分

[ArbitraryServerID]
        host = mysqlserver.example.com
        # host = 1.2.3.4
        instance = MYSQLSERVER
        port = 1433
        tds version = 8.0
        text size = 64512
        client charset = UTF-8

现在可以使用 isql 测试连接

isql -S ArbitraryServerID -U 'username' -P 'password'

假设工作正常,重新启动php-fpm

service php-fpm restart

在您的 PHP 应用程序中,PDO 连接字符串应类似于:

$mssql_server   = 'ArbitraryServerID';
$mssql_user     = 'username';
$mssql_pw       = 'password';
$dbx_mssql = new PDO("odbc:DRIVER=FreeTDS;SERVERNAME=$mssql_server;Database=AppDatabase", $mssql_user, $mssql_pw);

就是这样,您现在有了到远程 SQLServer 实例的有效 ODBC 连接。

于 2021-04-21T20:25:21.137 回答