Configurar PHP para conectar a Oracle

En algunas ocasiones nos encontramos que la base de datos a la que tenemos que conectar desde PHP es Oracle en vez de MySQL, y el problema suele ser que no el yum install php-oracle o apt-get install php-oracle no nos funciona.
¿Qué podemos hacer? ... os cuento lo que yo hago:

  1. Lo primero que debemos hacer es descargar los RPMs del InstantClient de Oracle en /opt/software/oracle. Nos servirán oracle-instantclient11.1-basic-11.1.0.7.0-1.i386.rpm y oracle-instantclient11.1-devel-11.1.0.7.0-1.i386.rpm. Luego los instalaremos ejecutando:
    rpm -ivh /opt/software/oracle/oracle-instantclient11.1-*
  2. Añadir al entorno las variables que necesita Oracle para ejecutarse. Para ello, añadir las siguientes lineas al fichero /etc/profile:
    export ORACLE_HOME=/usr/lib/oracle/11.1/client
    export NLS_LANG=spanish_spain.WE8ISO8859P15
    export TNS_ADMIN=$ORACLE_HOME/network/admin
    export LD_LIBRARY_PATH=/usr/local/lib:/usr/lib/:/lib:$LD_LIBRARY_PATH
    export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$LD_LIBRARY_PATH
    export PATH=$PATH:$ORACLE_HOME/bin
    Sería recomendable cerrar sesión y volverla abrir para que se carguen estas variables en nuestro entorno.
  3. Lo siguiente será copiar un fichero tnsnames.ora al directorio $ORACLE_HOME/network/admin desde otro servidor de aplicaciones, en el que ya nos funcione la conexión a la BBDD de Oracle.
  4. Para instalar las librerías de Oracle, lo haremos mediante PECL, que es algo así como el CPAN para Perl, pero para PHP.
    yum install php-pear php-devel

    pecl install oci8
    Cuando nos pregunte, decirle que autodetecte la instalacion. Cuando instalamos lo hacemos desde los RPM lo hace automaticamente. Al terminar de compilar e instalar nos habrá dejado la libreria en /usr/lib/php/modules/. Ahora deberíamos incluirla en /etc/php.ini añadiendo la siguiente línea dentro de la sección de Dynamic Extensions, entorno a línea número 620:
    extension=oci8.so
  5. Reiniciar el servicio de Apache, para que PHP cargue las librerías de Oracle...
    /etc/init.d/httpd restart
  6. Crear un fichero /var/www/html/infophp.php con el siguiente contenido:
    <?php
    phpinfo();
    ?>
    Abrir la URL desde un navegador http://MISERVIDOR/infophp.php, para comprobar las variables de entorno y que PHP ha cargado la librería oci8.
  7. Cuando hayamos comprobado, que ya tenemos el PHP configurado para poder conectar a Oracle, podremos crear nuestra primera página:
    <?php

    # Inicializar la conexión a Oracle
    $conn = oci_connect('XXLOGINXX', 'XXCONTRASEÑAXX', 'XXSIDXX');

    # Preparar la Query
    $query = 'select table_name from user_tables';

    # Conectar realmente y lanzar la consulta...
    $stid = oci_parse($conn, $query);
    oci_execute($stid, OCI_DEFAULT);

    # Lanzar la consulta
    while ($row = oci_fetch_array($stid, OCI_ASSOC)) {

    # Recuperar las filas de la consulta
    foreach ($row as $item) {
    echo $item." ";
    }
    echo "<br>\n";
    }

    # Cerrar la conexión con Oracle
    oci_free_statement($stid);
    oci_close($conn);

Cuando reiniciemos el servidor seguramente nos habrá dejado de funcionar. Es importante añadir al script /etc/init.d/apache, después del bloque de comentarios inicial la línea:
. /etc/profile
Esto pasa porque el cliente Oracle necesita estas variables definidas en el entorno, y cuando se reinicia el servidor, el proceso init, no incializa este entorno y ejecuta estos ficheros. Al añadirlo al demonio de arranque de Apache, nos aseguramos que Apache las tenga inicializadas cuando init lo llame durante el inicio del servidor.

La foto la he sacado del album de CalEvans en flickr

3 comentarios:

AlucarD64 dijo...

Muy buen tutorial, muchas gracias me ha servido bastante para fedora 12 con oracle 10gR2

Nacho Santos dijo...

Por la experiencia, veo recomendable informar las variables relativas al cliente de Oracle tan solo a quien las necesite. Es decir, utilizar el fichero ennvars de Apache y dejar el /etc/profile para otras cosas.
De este modo, podrás tener varios apaches compilados, con varias versiones de php y estos utilizando los clientes de Oracle que consideres oportunos.

En mi situación actual, tengo dos clientes de Oracle Instant Client 10g y 11g y una base de datos Oracle XE. Tuve que deshacer el trabajo y configurar el servidor apache a usar solo la versión 10g porque necesitaba conectar a una base de datos 8i.


root@gvhidra-test:~# vi /usr/local/httpd-2.2.8/bin/envvars
#Configuracion para hacer accesible el Oracle al usuario www-dev (en v10 por human)
export ORACLE_BASE="/usr/local/lib/instantclient_11_2"
export ORACLE_HOME=$ORACLE_BASE
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$LD_LIBRARY_PATH
#Para recargar la libreria por si se usa otra distinta a la compilada en php
#export LD_PRELOAD=$ORACLE_HOME/libclntsh.so.11.1
export TNS_ADMIN=$ORACLE_BASE
export PATH=$ORACLE_HOME:$PATH
export NLS_LANG=SPANISH_SPAIN.WE8ISO8859P15


root@gvhidra-test:~# service apache-dev stop
root@gvhidra-test:~# service apache-dev start

AndreGirl dijo...

Me ha sido de gran ayuda tu guía :) Eres genial, pero he encontrado algo igual de sencillo en esta otra pagina, espero les sirva como a mi :D