如何在 CentOS 7.6 中使用 sqlsrv 连接到 SQL 服务器?

How to connect to SQL server using sqlsrv in CentOS 7.6?

我正在设置新服务器并尝试使用 "sqlsrv" extension/module 和 PHP 7.3 运行 连接到 Microsoft SQL Server Express 2014 的数据库] 在 CentOS 7.6 中,但失败了。然而,在 XAMPP 中使用相同的方法,它确实有效!

我已经根据 Microsoft 页面的说明安装了 php 驱动程序:https://docs.microsoft.com/en-us/sql/connect/php/installation-tutorial-linux-mac?view=sql-server-2017

在第 3 步中,前两种方法无效,因此我从 Remi 存储库安装了 PHP 驱动程序:

[~]$ sudo yum install php-sqlsrv

这是已安装软件包的列表:

$ sudo yum list installed *php*
Installed Packages
php.x86_64                                                7.3.4-1.el7.remi                                   @remi-php73
php-cli.x86_64                                            7.3.4-1.el7.remi                                   @remi-php73
php-common.x86_64                                         7.3.4-1.el7.remi                                   @remi-php73
php-devel.x86_64                                          7.3.4-1.el7.remi                                   @remi-php73
php-fedora-autoloader.noarch                              1.0.0-1.el7                                        @epel
php-json.x86_64                                           7.3.4-1.el7.remi                                   @remi-php73
php-pdo.x86_64                                            7.3.4-1.el7.remi                                   @remi-php73
php-pear.noarch                                           1:1.10.9-2.el7.remi                                @remi-php73
php-process.x86_64                                        7.3.4-1.el7.remi                                   @remi-php73
php-sqlsrv.x86_64                                         5.6.1-1.el7.remi.7.3                               @remi-php73
php-xml.x86_64                                            7.3.4-1.el7.remi                                   @remi-php73

$ sudo yum list installed unixODBC*
Installed Packages
unixODBC.x86_64                                    2.3.7-1.rh                               @packages-microsoft-com-prod
unixODBC-devel.x86_64                              2.3.7-1.rh                               @packages-microsoft-com-prod

$ sudo yum list installed msodbcsql*
Installed Packages
msodbcsql.x86_64                                  13.1.9.2-1                                @packages-microsoft-com-prod
msodbcsql17.x86_64                                17.3.1.1-1                                @packages-microsoft-com-prod

虽然,我没有使用命名实例,但根据这个常见问题解答: https://github.com/Microsoft/msphpsql/wiki/FAQ#connect-to-named-instances

我可以使用独立于 PHP 驱动程序的 ODBC 驱动程序连接到 Microsoft SQL 服务器。通过使用 "isql":

[~]$ isql -v MSSQLTest uid password

我遇到过的一些类似问题是:

https://github.com/Microsoft/msphpsql/issues/703
https://github.com/Microsoft/msphpsql/issues/679
https://github.com/Microsoft/msphpsql/issues/470

但是当使用 sqlsrv 时,没有任何效果。

我的PHP连接代码(在XAMPP工作):

// xx.xx.xx.xx = My Public IP
// yyyy = My Port
$serverName = "xx.xx.xx.xx,yyyy"; //serverName\instanceName
$connectionInfo = array( "Database"=>"MyDB", "UID"=>"MyUID", "PWD"=>"MyPWD", "CharacterSet" => "UTF-8");
$conn = sqlsrv_connect( $serverName, $connectionInfo);

if( $conn ) {
     echo "Connection established.<br />";
}else{
     echo "Connection could not be established.<br />";
     die( print_r( sqlsrv_errors(), true));
} 

// ...Query part

输出:

Connection could not be established.
Array ( [0] => Array ( [0] => HYT00 [SQLSTATE] => HYT00 [1] => 0 [code] => 0 [2] => [Microsoft][ODBC Driver 17 for SQL Server]Login timeout expired [message] => [Microsoft][ODBC Driver 17 for SQL Server]Login timeout expired ) [1] => Array ( [0] => 08001 [SQLSTATE] => 08001 [1] => 10013 [code] => 10013 [2] => [Microsoft][ODBC Driver 17 for SQL Server]TCP Provider: Error code 0x271D [message] => [Microsoft][ODBC Driver 17 for SQL Server]TCP Provider: Error code 0x271D ) [2] => Array ( [0] => 08001 [SQLSTATE] => 08001 [1] => 10013 [code] => 10013 [2] => [Microsoft][ODBC Driver 17 for SQL Server]A network-related or instance-specific error has occurred while establishing a connection to SQL Server. Server is not found or not accessible. Check if instance name is correct and if SQL Server is configured to allow remote connections. For more information see SQL Server Books Online. [message] => [Microsoft][ODBC Driver 17 for SQL Server]A network-related or instance-specific error has occurred while establishing a connection to SQL Server. Server is not found or not accessible. Check if instance name is correct and if SQL Server is configured to allow remote connections. For more information see SQL Server Books Online. ) ) 

如何获得"Connection established."?


根据 Remi Collet 的回答更新:

$ sqlcmd -S mypublicip,myport -U user -P secret -Q "SELECT @@version"

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Microsoft SQL Server 2014 - 12.0.2000.8 (X64)
        Feb 20 2014 20:04:26
        Copyright (c) Microsoft Corporation
        Express Edition (64-bit) on Windows NT 6.3 <X64> (Build 14393: )

$ php -r ' echo"+ Connection:\n"; $conn = sqlsrv_connect("mypublicip,myport", array("UID" => "user", "PWD" => "secret")); if ($conn) { echo"+ Query: \n"; $query = sqlsrv_query($conn, "SELECT @@version"); if ($query) { echo"+ Result:\n"; print_r($row = sqlsrv_fetch_array($query, SQLSRV_FETCH_NUMERIC)); } } '

+ Connection:
+ Query:
+ Result:
Array
( 
    [0] => Microsoft SQL Server 2014 - 12.0.2000.8 (X64)
        Feb 20 2014 20:04:26
        Copyright (c) Microsoft Corporation
        Express Edition (64-bit) on Windows NT 6.3 <X64> (Build 14393: )

) 

如您所见,命令行中的 sqlcmd 和 运行 PHP 脚本都可以正常工作!

但是在通过 FTP 上传相同的 PHP 脚本并从浏览器访问后,输出如下:

+ Connection:

只有一行。然后,我将 php-sqlsrv 更新为 5.6.1-2.el7.remi.7.3

而且,SELinux 配置已经完成:

$ sudo setsebool -P httpd_can_network_connect_db 1

这是来自 "getsebool" 的值:

httpd_anon_write --> off
httpd_builtin_scripting --> on
httpd_can_check_spam --> off
httpd_can_connect_ftp --> off
httpd_can_connect_ldap --> off
httpd_can_connect_mythtv --> off
httpd_can_connect_zabbix --> off
httpd_can_network_connect --> off
httpd_can_network_connect_cobbler --> off
httpd_can_network_connect_db --> on
httpd_can_network_memcache --> off
httpd_can_network_relay --> off
httpd_can_sendmail --> off
httpd_dbus_avahi --> off
httpd_dbus_sssd --> off
httpd_dontaudit_search_dirs --> off
httpd_enable_cgi --> on
httpd_enable_ftp_server --> off
httpd_enable_homedirs --> on
httpd_execmem --> off
httpd_graceful_shutdown --> on
httpd_manage_ipa --> off
httpd_mod_auth_ntlm_winbind --> off
httpd_mod_auth_pam --> off
httpd_read_user_content --> off
httpd_run_ipa --> off
httpd_run_preupgrade --> off
httpd_run_stickshift --> off
httpd_serve_cobbler_files --> off
httpd_setrlimit --> off
httpd_ssi_exec --> off
httpd_sys_script_anon_write --> off
httpd_tmp_exec --> off
httpd_tty_comm --> off
httpd_unified --> on
httpd_use_cifs --> off
httpd_use_fusefs --> off
httpd_use_gpg --> off
httpd_use_nfs --> off
httpd_use_openstack --> off
httpd_use_sasl --> off
httpd_verify_dns --> off

运气不好,还是和使用5.6.1-1.el7.remi.7.3

版本时一样的结果

注意:我还有两个版本的 Microsoft ODBC Driver for SQL Server,13 和 17(我不确定这是否会导致问题,并且不知道删除旧的)

P.S。我没有尝试过其他方法,因为我现在只对 sqlsrv 扩展感兴趣,所以其他方法可能有用!



最后更新:

原因:SELinux配置中"httpd_can_network_connect"的值设置为"off".

解决方案:开启"httpd_can_network_connect"值,通过这个命令。

$ sudo setsebool -P httpd_can_network_connect 1

然后让 httpd 重新启动一次:

$ sudo systemctl restart httpd

检查结果,现在一切正常!

抱歉,使用 Microsoft SQL Server from PHP 中的所有示例,我无法重现您的问题。连接正常。

  • 检查服务器是否准备好服务器客户端连接
  • 检查防火墙配置(至少应该允许 1433,检查使用端口的 netstat)
  • 使用 sqlcmd 命令从命令行检查(来自 mssql-tools 包)
  • 使用简单的 PHP 脚本从命令行检查
  • 检查 SElinux 配置 (httpd_can_network_connect)

P.S。请注意,我已经推送了 php-sqlsrv 的一个小更新,它正确地拉取了 msodbcsql17 而不是 msodbcsql。