ODBC, FreeTDS and Microsoft SQL (and php)
What is it all about
I had to connect to a MS SQL server from php from a Linux box. First I tried with php mssql_* functions, but they are not compiled nor the php MS SQL support is available through deb packages.
So I tried to use odbc_* functions but after specifying everything I thought reasonable for the connection I was still havign this error:
Warning: odbc_pconnect(): SQL error: [unixODBC][Driver Manager]Data source name not found, and no default driver specified, SQL state IM002 in SQLConnect in /home/ivan/Documents/kerberos/work/gorilla/scripts/cover_note/dbconn.php on line 11
no connectionI googled and I discovered I had to install ODBC drivers... at my surprise installing unixodbc was not enough.
I didn't want to install anything not in Debian, not I was willing to compile php and make my own deb package.
What you've to look at is here even if it has a small error (-t vs. -f in the examples):
Linux/UNIX ODBC and expecially here: unixODBC - MS SQL Server/PHP
Step by step guide
Getting the right stuff for odbc and FreeTDS in sarge and sid
In sarge and sid the odbc stuff has the same name unixodbc. You don't want to take it in directly if you're planning to use it with PHP since it will be taken in by php*-odbc.
odbcunix won't be enough to connect to MS SQL, you need a driver and the best easiest one to install I've found was FreeTDS.
You may find useful a set of GUI utilities in unixodbc-bin. I used ODBCConfig just to discover I didn't have any driver installed.
It may be puzling, even if it is written in the description of the package, to discover that the binaries of the lib in sarge are inside a -dev package: freetds-dev. In sid (and maybe testing/etch) the libs are in tdsodbc.
Setting up the driver and the DSN
- Log as root
- Create a file in your home a tds.driver.template (or any reasonabel choice) file with this content:
[FreeTDS]
Description = FreeTDS 0.63-3, unixodbc 2.2.11-13
Driver = /usr/local/freetds/lib/libtdsodbc.so - Create a DSNNAME.datasource file with this content:
[DSNNAME]
Driver = FreeTDS
Description = A good description of your DB
Trace = No
Server = [hostname]
Port = 1433
Database = [Databasename]
#UID = [USERNAME]
#PWD = [PASSWORD]
#LogonUser=[USERNAME]
#LogonAuth=[PASSWORD] - Run odbcinst -i -d -f tds.driver.template
- Run odbcinst -i -s -l -f DSNNAME.datasource for a system DSN
Using a system DSN will make it available to other users. Otherwise create the user DSN from the user that will access the DB. Consider that if you're using php as cgi it may run under the web server user and it may be tricky to use a user DSN.
If you've several instance of MS SQL on the same box, you just have to adjust the Port as explained here:
Connection attributes
"Server: Hostname of a server. Used in an ODBC-only configuration. As of version 0.64 you can specify a Microsoft SQL Server instance in the form of server\instance. This isn't required to connect to an instance, and is in fact slightly slower to set up the conncection, because it entails an extra round trip to the server. To avoid that, ask to your administrator for the port number of each instance, and create separate server entries for each one."
Test the DSN and driver
isql -v DSNNAME USERNAME PASSWORD
This works on sid and sarge.
Installing and testing PHP support
Now install php4-odbc on sarge or php5-odbc on sid (testing/etch?) end test this code:
#!/usr/bin/php -q
<?php
$db_dsn="DSNNAME";
$db_user="USERNAME";
$db_pass="PASSWORD";
if ($conn=odbc_pconnect($db_dsn, $db_user, $db_pass)) {
$SQLstr = "SELECT top 10 * FROM sysobjects";
$rs = odbc_exec($conn,$SQLstr);
while($row = (odbc_fetch_array($rs)))
print_r($serv);
} else { print "no connection\n"; }
?>Unfortunately on sid I get a Segmentation fault but on sarge it works.
Security
Consider that when you access the DB through isql in the way explained above you're exposing the pw/un to anyone typing ps aux on your system.
I doubt storing them on your system DSN will improve the situation.
FreeTDS, Sybase and sqsh
isql is a bit of pain. You can't do things like \i somestuff.sql etc... as you can do in psql. But skipping ODBC and going directly through FreeTDS and use sqsh.
Here you can find some notes about using sqsh on MS SQL
PHP & mssql_ vs. sybase_
I haven't tested yet but if you need to connect to MS SQL through PHP another and maybe more efficient (performance and installation hassle) solution would be to use sybase_ class of functions.
To use them you'll have to install php4-sybase or php5-sybase
Other links
Accessing Microsoft SQL Server from PHP under Apache on UNIX or Linux
Accessing ODBC Databases with PHP and PEAR DB
Enabling ODBC support in PHP under Apache pointing out some problems you may have