Acceder desde Linux a SQL Server con PHP

Este artículo ´tiene como base el artículo en inglés de Robert González con modificaciones para openSUSE y mejoras en algunos scripts.

Para acceder a SQL server desde Linux con PHP es necesario utilizar la librería de PHP MSSQL pero para instalar la misma es necesario tener previamente instalado FreeTDS, una biblioteca de código abierto que permite a los clientes de máquinas Linux hablar con servidores SQL Server y Sybase.

Este manual es para instalar FreeTDS y MSSQL en un servidor Linux openSUSE 11.4 con una versión de PHP 5.3.7 dev y permitir su comunicación con servidor SQL Server 2008 R2 alojado en un Failover Cluster con 2 nodos basados en Windows Server 2008 R2.

Compilar e instalar FreeTDS en openSUSE 11.4

Actualizado el 12 de abril de 2013.

Lo primero es descargar la última versión estable de la biblioteca FreeTDS (a fecha de este post la 0.82 0.91) y desempaquetar el código fuente a un directorio en nuestro servidor Linux. Una vez que el código fuente está descomprimido, cambiamos al directorio donde se encuentra la fuente y configuramos e instalamos la biblioteca. Veamos estos pasos en comandos para la consola:

$ wget ftp://ftp.ibiblio.org/pub/Linux/ALPHA/freetds/stable/freetds-stable.tgz 
$ wget ftp://ftp.astron.com/pub/freetds/stable/freetds-stable.tgz
$ tar xzvf freetds-stable.tgz
$ cd freetds-0.82
$ cd freetds-0.91

Para que PHP pueda comunicarse con SQL Server es necesario configurar FreeTDS con db-lib que permite el acceso a servidores Sybase y SQL Server de Microsoft (la extensión de PHP MSSQL es la destinada exclusivamente a los servidores de Microsoft).

$ ./configure --prefix=/usr/local/freetds --enable-msdblib
$ make
$ sudo make install

Antes de hacer cualquier otra cosa después del make install debemos asegurarnos que se han copiado todos los archivos necesarios de FreeTDS. En la rutina de instalación, debido a un cambio realizado por parte de los desarrolladores de FreeTDS, hay dos archivos que son necesarios para construir la extensión MSSQL y que no son copiados al directorio. Estos archivos son necesarios y deben ser copiados en el directorio de instalación de FreeTDS.

Para ello copiamos desde el directorio del código fuentes de FreeTDS estos archivos (los comandos siguientes presuponen que aún seguimos en el directorio fuente de FreeTDS):

sudo cp include/tds.h /usr/local/freetds/include
sudo cp src/tds/.libs/libtds.a /usr/local/freetds/lib

Compilar e instalar MSSQL en PHP 5.3.7 dev en openSUSE 11.4

Lo primero que debemos hacer es descargarnos desde la página oficial de PHP el código fuente de nuestra versión de PHP, yo cometí un error y me descargue la versión 5.3.6 pero se ve que MSSQL es plenamente compatible con esta distribución de PHP (también es válido para PHP 5.3.5).

$ wget http://es.php.net/get/php-5.3.6.tar.gz/from/this/mirror
$ wget http://museum.php.net/php5/php-5.3.6.tar.gz
$ tar xzvf php-5.3.6.tar.gz

Mi preferencia es dejar el código fuente intacto y compilar con copias de los archivos es por ello que me voy a crear un directorio ya allí moveré todos los archivos necesarios para compilar la librería MSSQL.

$ cd /usr/tmp
$ mkdir source

Una vez creado el directorio para los archivos temporales debemos ir al directorio descomprimido con los códigos fuentes de PHP y copiar los archivos siguientes al directorio que hemos creado a tal fin:

$ cp ext/mssql/config.m4 /usr/tmp/source
$ cp ext/mssql/php_mssql.c /usr/tmp/source
$ cp ext/mssql/php_mssql.h /usr/tmp/source

Compilar MSSQL en PHP 5.3.7 dev

Debemos asegurarnos que tenemos el paquete php5-dev (php5-devel) instalado de no ser así lo tenemos que instalar con YAST, este paquete es el que nos permite compilar nuevas extensiones desde la línea de comandos.


Desde el directorio temporal que hemos creado (en mi caso source) ejecutamos:

$ phpize
$ ./configure --with-mssql=/usr/local/freetds
$ make
$ make install

Si todo ha salido bien nos debería salir la siguiente línea en el make

Build complete.
Don't forget to run 'make test'.

Y luego en el make install

Installing shared extensions:     /usr/lib64/php5/extensions/

Actualización 12 de abril de 2013

Con FreeTDS 0.91 el make puede fallar dándonos el siguiente error php_mssql.h:68:24: error: redefinition of typedef LPBYTE. Para evitar esto debemos ir al archivo php_mssql.h y eliminar la línea typedef unsigned char *LPBYTE;.

El error con la constante LPBYTE parece ser un problema a la hora de incluir los archivos fuente. Esta constante se define en tanto php_mssql.h como en sqlfront.h. El archivo de sqlfront.h mira para ver si la constante PHP_MSSQL_H está definida y se salta la redefinición si es así, para evitar el conflicto. Si  incluímos el archivo php_mssql.h primero la constante se ajustará y todo saldrá según lo planeado. Sin embargo, si se incluye sqlfront.h primero, la constante no se establecerá y será definida LPBYTE (ilegalmente) en dos lugares.

Si bien el texto de definición es diferente en ambos archivos la definición es equivalente (puntero a un unsigned char), por lo que la solución rápida y sucia es comentar (mejor eliminar) esa línea en php_mssql.h y continuar.

Con esta opción ya tendríamos el archive mssql.so compilado y ubicado en nuestro directorio de extensiones de PHP, suele ser /etc/php5/extensions/ /usr/lib64/php5/extensions/. Si por un casual no encontramos el directorio dónde estan definidas las extensiones podemos utilizar la función para buscar archivos en linux y buscamos una extension que si sepamos que existe, por ejemplo la de MySQL:

$ find / -name "*mysql.so*"

Configurar PHP para usar la nueva extensión que acabamos de hacer

Ahora tenemos que decirle a PHP cómo usar la nueva extensión que acabamos de construir. Para ello tenemos que crear un archivo INI para la extensión y colocarlo dentro del directorio de configuraciones de extensiones de PHP, donde pueda encontrarlo. En mi máquina PHP busca estos archivos ini en / etc/php5/conf.d /, en comandos sería así:

$ cd /etc/php5/conf.d/
$ sudo vim mssql.ini

Podemos utilizar cualquier otro editor e incluso otro nombre para el archivo, lo único que debemos mantener es la extensión y el siguiente contenido:

; Enable the mssql extension
extension=mssql.so

Configurar FreeTDS y MSSQL para acceder a nuestro servidor SQL Server.

Ahora necesitamos configurar el entorno para cargar algunas variables necesarias cada vez que la máquina se inicia.

La extensión MSSQL necesita una variable de entorno con el fin de funcionar correctamente. Para asegurarnos que PHP puede utilizar la extensión de SQL Server tanto desde la línea de comandos como desde el servidor web necesitamos añadir una variable de entorno tanto en el script /etc /profile como en el archivo de configuración de apache.

Configurar la variable de entorno para la línea de comandos

$ sudo vim /etc/profile

Y agregamos al final del archivo la siguiente línea

export FREETDSCONF=/usr/local/freetds/etc/freetds.conf

Esto lo podemos hacer automáticamente con el siguiente comando

$ echo "export FREETDSCONF=/usr/local/freetds/etc/freetds.conf" >> /etc/profile

Configurar la variable de entorno en nuestro servidor web apache

Debemos editar el archivo httpd.conf y agregar la siguiente línea después del último INCLUDE

SetEnv FREETDSCONF /usr/local/freetds/etc/freetds.conf

Configurar FreeTDS

Con el fin de que la librería FreeTDS pueda comunicarse correctamente con el servidor SQL Server, un DSN de clases tiene que ser creado. Para hacer un DSN tiene que editar el archivo freetds.conf:

$ sudo vim /usr/local/freetds/etc/freetds.conf

Ir al final del archivo y agregue las líneas siguientes (asegúrese poner todos los valores de configuración para cada SERVERNAME):

;--- Custom MSSQL server name ---
; THIS CAN BE ANY NAMED SERVER REFERENCE YOU WANT TO CREATE
[SERVERNAME]
; This is the host name of the MSSQL server
host=HOSTNAME
; This is the port number to use
port=PORTNUMBER
; This is the TDS version to use for anything over Server 2000
tds version=8.0

Algunas consideraciones: el puerto suele ser siempre el 1433 en todas las instalaciones de SQL Server a no ser que se haya cambiado manualmente. Para servidores SQL Server modernos, superiores a la versión 2000 es necesario poner como la versión del TDS (Tabular Data Stream) la 7 u 8, en nuestro caso para el server 2008 R2 he puesto la 8.0.

En el hostname podemos poner una IP, aqui os dejo 2 ejemplos de configuración:

[logisticsServer]
host = ntmachine.localdomain
port = 1433
tds version = 7.0

[intranetServer]
host = 192.168.1.145
port = 1433
tds version = 4.2

Ahora tenemos que añadir la biblioteca FreeTDS a la pila de las bibliotecas cargadas por el sistema.

$ sudo vi /etc/ld.so.conf

Vamos al final del archivo y agregamos la siguiente línea:

/usr/local/freetds/lib

Igualmente esto lo podemos hacer de manera abreviada con el comando:

$ echo "/usr/local/freetds/lib" >> /etc/ld.so.conf

Reiniciar apache

Como todo lo que implica un cambio en el entorno de PHP o la configuración de su equipo es necesario reiniciar el servidor web. Estoy asumiendo que este se basa en un servidor apache. Si no, necesitarás saber cómo detener e iniciarlo o, al menos, saber reiniciar el equipo:

$ rcapache2 restart

Para comprobar si la línea de comandos ejecuta MSSQL podemos ejecutar:

$ php –m

Y entre el listado de módulos debe aparecer MSSQL.

Para hacer lo mismo con el servidor apache utilizaremos phpinfo() y buscamos MSSQL.

Para probar que tenemos conexión con nuestro servidor SQL Server nos bastaría con el siguiente script:

<?php
$server = 'SERVERNAMEONDNS';
// Connect to MSSQL
$link = mssql_connect($server, 'user', 'password');
if (!$link) {
die('Something went wrong while connecting to MSSQL');
}
?>

Tener en cuenta lo siguiente:
  • SQL Server debe admitir conexiones remotas
  • En el servidor de Windows debe estar abierto el puerto 1433 en el firewall
  • El nombre que pongamos en nuestro script NO es la IP ni el nombre de la máquina, es el nombre que hemos dado a esta configuración en el archivo FreeTDS, la directiva SERVERNAME.

Comentarios

Anónimo ha dicho que…
buen dia!

Para hacer este proceso tengo que conectarme desde ssh de mi servidor web para hacer estos pasos?

Saludos!
Reynier ha dicho que…
si claro, todo esto es desde la consola
Anónimo ha dicho que…
saludos... seguí uno a uno los pasos pero me sale el tipico mensaje de que no se pudo conectar al servidor...

será q hice algo mal?? será que definitivamente es incompatible...

de que forma reversaría todo este proceso para poder instalar otro driver?? ej: sqlsrv

gracias de antemano, excelente pagina!
Luis ha dicho que…
para servidor centos que líneas de comandos hay que seguir
Reynier ha dicho que…
Para CentOS lo puedes ver aqui http://scriptinside.blogspot.com.es/2015/05/freetds-php-mssql-y-centos-66.html