我需要重新编译/安装php来添加mssql扩展吗?

时间:2013-07-24 19:57:07

标签: php sql-server linux odbc freetds

我有一个运行php的系统,我最近需要添加到MSSQL数据库的连接。我正确安装/配置了FreeTDS和UnixODBC,我可以在python中成功查询,并通过tsql和isql等实用程序。看了phpinfo()我发现我没有'sqlsrv'部分,并且我的php扩展目录中没有mssql.so文件。

我想将此添加到我的系统而无需重新编译/安装php。我是否能够找到并下载mssql.so文件,将其放入我的扩展目录,将extension=/path/to/mssql.so添加到我的php.ini文件中,然后重新加载apache以使其正常工作?或者我需要采取更多步骤吗?

修改

系统正在使用PHP 5.2运行SLES11

编辑2:

我设法安装了php5-mssql扩展程序。我抓住了源代码,将其解压缩并复制了这些文件:

ext/mssql/config.m4
ext/mssql/php_mssql.c
ext/mssql/php_mssql.h

然后,在我将文件复制到的目录中,我运行了phpize(您需要安装php5-devel才能获得此工具),并按如下方式编译扩展名:

./configure --with-mssql=/usr/local/freetds
make

我还必须在php_mssql.c中添加一行并注释掉一行才能真正正确编译(不是每个人都需要这样做):

{NULL,NULL,NULL}
/*PHP_FE_END*/

这创建了/ php_mssql / modules /中的mssql.so文件(相对于我编译代码的地方),我可以将其移动到我的扩展目录(你可以用php -i | grep extensions找到它)。我在我的php.ini文件中添加了extension=mssql.so;但是,phpinfo()中仍然没有'sqlsrv部分。

某些连接方法似乎部分有效:

从shell运行以下代码时,会显示<h1>Connection Success</h1>;但是在浏览器中打开时,mssql_connect行之后没有显示任何内容:

<?php
//*************************************************************************
//Open Database Connection
//*************************************************************************
//phpinfo();
$dbserver="MyServer";
$dbusername="user";
$dbpassword="pass";
$defaultdb="DBName";
$cn = mssql_connect($dbserver,$dbusername,$dbpassword) or die("Connection Error");
$db = mssql_select_db($defaultdb,$cn) or die("Database Error");
echo "<h1>Connection Success</h1>";
?>

所以看起来我部分地获得连接?当我尝试使用PDO对象时,我收到另一个错误:

代码:

<?php
$con = new PDO('odbc:host=MyServer;dbname=DBName','user','pass');
?>

错误:

PHP Fatal error:  Uncaught exception 'PDOException' with message 'SQLSTATE[IM002] SQLDriverConnect: 0 [unixODBC][Driver Manager]Data source name not found, and no default driver specified' in /path/to/php/file/test3.php:3
Stack trace:
#0 /path/to/php/file/test3.php(3): PDO->__construct('odbc:host=MySer...', 'user', 'pass')
#1 {main}
  thrown in /path/to/php/file/test3.php on line 3

我也尝试了以下内容(假设上一代码中的PDO语句/ DSN不正确):

<?php
try {
        $db = new PDO("odbc:Driver=FreeTDS; Server=MyServer; Port=1433; Database=DBName; UID=user; PWD=pass;");
} catch (PDOException $exception) {
        die("$exception");
}
echo "<h1>Success!</h1>";
?>

这显示了来自shell的<h1>Success!</h1>,但在我的网络浏览器中显示以下错误:

exception 'PDOException' with message 'SQLSTATE[08001] SQLDriverConnect: 0 [unixODBC][FreeTDS][SQL Server]Unable to connect to data source' in /path/to/php/file/test4.php:3 Stack trace: #0 /path/to/php/file/test4.php(3): PDO->__construct('odbc:Driver=Fre...') #1 {main}

3 个答案:

答案 0 :(得分:1)

在ODBC中,错误消息包含消息开头的[]中的元素,最右边的元素是报告错误的链的一部分(请参阅ODBC Diagnostics & Error Status Codes。所以,“[unixODBC] [驱动程序管理器]未找到数据源名称,并且unixODBC未报告任何默认驱动程序.UnixODBC所说的是传递给ODBC API的字符串SQLConnect或SQLDriverConnect不识别DSN(数据源名称)或ODBC驱动程序,并且没有默认DSN已定义。您可以通过运行odbcinst -j例如

来查找数据源的定义位置
$ odbcinst -j
unixODBC 2.2.14
DRIVERS............: /etc/odbcinst.ini
SYSTEM DATA SOURCES: /etc/odbc.ini
FILE DATA SOURCES..: /etc/ODBCDataSources
USER DATA SOURCES..: /home/martin/.odbc.ini
SQLULEN Size.......: 4
SQLLEN Size........: 4
SQLSETPOSIROW Size.: 2

此处,驱动程序在/etc/odbcinst.ini中定义,/ etc / odbc.ini中的系统数据源和/home/martin/.odbc.ini中的用户数据源。因为你可能在网络服务器下运行PHP,如果我是你,我会坚持使用系统数据源。您可以使用odbcinst -q -l -s列出系统数据源。您可以在Linux/UNIX ODBC找到关于Linux / ODBC的非常好的解释。

您的第二个错误“[unixODBC] [FreeTDS] [SQL Server]无法连接到数据源”由FreeTDS的SQL Server驱动程序报告,因此在这种情况下,您必须已将足够的信息传递给unixODBC以至少允许它识别驱动程序,加载它并在其中调用SQLConnect / SQLDriverConnect。您可以通过在unixODBC中启用跟踪来查看传递给unixODBC的SQLConnect / SQLDriverConnect的内容。您可以通过编辑odbcinst.ini文件(使用上面的odbcinst -j命令找到)并在其顶部添加以下内容来启用对unixODBC的跟踪:

[ODBC]
Trace           = yes
TraceFile               = /tmp/unixodbc.log

现在,当您运行php示例时,它将记录到/tmp/unixodbc.log所有ODBC API调用,您要查找的是SQLConnect或SQLDriverConnect。例如,当我使用用户名和密码XXX和YYY连接到名为mydsn的DSN时,我看到:

[ODBC][31521][1374740062.012973][SQLDriverConnect.c][687]
                Entry:            
                        Connection = 0x9d7d430            
                        Window Hdl = (nil)            
                        Str In = [DSN=mydsn;UID=XXX;PWD=********][length = 29]            
                        Str Out = 0xbfdeb83c            
                        Str Out Max = 512            
                        Str Out Ptr = 0xbfdeb638            
                        Completion = 0
                UNICODE Using encoding ASCII 'ISO8859-1' and UNICODE 'UCS-2LE'

                DIAG [01000] [Easysoft][SQL Server Driver][SQL Server]Changed database context to 'master'.

                DIAG [01000] [Easysoft][SQL Server Driver][SQL Server]Changed language setting to us_english.

注意,此连接成功,它清楚地显示连接字符串的一部分是DSN = mydsn,而mydsn在我的/etc/odbcinst.ini中作为DSN存在。

isql可以与某些启用ODBC的应用程序不同,因为isql调用ODBC API SQLConnect,而现在大多数ODBC应用程序都支持ODBC 3并使用SQLDriverConnect。主要区别在于SQLConnect仅提供3个参数,DSN名称,用户名和密码,其中SQLDriverConnect被赋予定义连接的单个属性/值对字符串。我只告诉你这个,所以你知道isql如何工作以及其他不可能的工作。

然而,在第二种情况下,当你检查你的跟踪时,你会看到unixODBC有足够的东西来识别驱动程序,加载它并调用freeTDS的ODBC驱动程序,错误“无法连接到数据源”来自freeTDS 。所以,我建议您的DSN可能正常,并且您的freetds.conf在某种程度上是不正确的。由于我自己不使用freeTDS,我不确定,但我听说你可以使用ODBC与freeTDS,而无需参考freetds.conf文件和基于你是否使用Server或ServerName的交换机。我确信freeTDS网站上有很多例子。

答案 1 :(得分:0)

以下是我从LAMP(Ubuntu)堆栈连接到MS SQL服务器的方法:

/etc/odbc.ini

# Define a connection to a Microsoft SQL server
# The Description can be whatever we want it to be.
# The Driver value must match what we have defined in /etc/odbcinst.ini
# The Database name must be the name of the database this connection will connect to.
# The ServerName is the name we defined in /etc/freetds/freetds.conf
# The TDS_Version should match what we defined in /etc/freetds/freetds.conf
[mssql]
Description             = MSSQL Server
Driver                  = freetds
Database                = XXXXXX
ServerName              = MSSQL
TDS_Version             = 8.0

/etc/odbcinst.ini

# Define where to find the driver for the Free TDS connections.
[freetds]
Description     = MS SQL database access with Free TDS
Driver          = /usr/lib/i386-linux-gnu/odbc/libtdsodbc.so
Setup           = /usr/lib/i386-linux-gnu/odbc/libtdsS.so
UsageCount      = 1

/etc/freetds/freetds.conf

# The basics for defining a DSN (Data Source Name)
# [data_source_name]
#       host = <hostname or IP address>
#       port = <port number to connect to - probably 1433>
#       tds version = <TDS version to use - probably 8.0>

# Define a connection to the Microsoft SQL Server
[mssql]
        host = XXXXXX
        port = 1433
        tds version = 8.0

这是PHP代码:

$con = new PDO('dblib:host=mssql;dbname=MyDB', 'domain\username', 'password');

您可能需要为您的操作系统稍微调整一下。要在Ubuntu上安装必要的软件,我做了类似的事情:

sudo apt-get install php5-odbc php5-sybase tdsodbc

答案 2 :(得分:-1)

使用PDO并安装此http://www.php.net/manual/en/ref.pdo-sqlsrv.php

我总是使用PDO它可以轻松地与不同的数据库驱动程序和相同的PHP代码进行所需的所有数据库交互。除了查询语言有时有点不同。

对于MSSQL,您只需要添加驱动程序,只需粘贴.dll,将条目添加到conf.ini并重新启动apache。