terça-feira, 8 de janeiro de 2008

Ligação a servidor Oracle a partir de RHEL4 ou CentOS4 sem recompilar Apache/PHP

Sumário: Configuração de uma Ligação ODBC a servidor Oracle 10 a partir de servidor Linux RHEL4/CentOS4.


Há cerca de três semanas colocou-se-me a necessidade de ligar a um servidor Oracle para depositar dados a partir de uma aplicação em PHP (PHP 5.2.x mais precisamente, mas será igual para PHP4).
Após percorrer vários fóruns e blogs rapidamente cheguei à conclusão que todas as formas de utilizar um driver Oracle de forma nativa em PHP envolviam a recompilação do Apache e do PHP, situação a evitar, do meu ponto de vista, por "quebrar" futuras actualizações do sistema via yum já que os RPMs desses pacotes teriam de ser desinstalados e substituidos por versões compiladas manualmente a partir da fonte. Também não estava interessado em manter uma infra-estrutura completa de gcc/glibc/headers/etc,etc para compilação, só para conseguir acrescentar ao PHP a capacidade de ligar a uma base de dados remota.

Na semana que passou, a necessidade dessa ligação tornou-se mais premente, e procurei desesperadamente por uma alternativa à solução mais vista. Por sorte ocorreu-me efectuar a ligação através de ODBC (unixODBC mais especificamente), pois é uma forma de ligação ao SQL Server que utilizo em alguns servidores com PHP 5.2 pois nunca encontrei pacotes RPM de php-mssql para essas versões de PHP, que creio não podem ser fornecidas por questões de licenciamento.

A utilização de ODBC em PHP para ligar ao SQL Server funciona bem, se tivermos cuidado com os campos de base de dados com mais de 255 caracteres que causam alguns problemas. Peço desculpas, esta questão seria para outro post, fica aqui apenas a referência.

A ideia era então instalar o suporte a Oracle no servidor, configurar a ligação ODBC e utilizar essa ligação a partir do PHP.

O primeiro passo consiste em instalar o Oracle Instant Client, o SQL*Plus e as bibiliotecas ODBC da Oracle, que são fornecidas gratuitamente pela Oracle (requer registo no site). Optei por instalar as versões em formato RPM para Linux x86, tendo o cuidado para fazer os downloads para a mesma versão (no meu caso optei pela versão 11.x, que era a mais recente, apesar de o servidor Oracle ser 10.x).

A instalação dos pacotes no servidor Linux é feita através do comando:

rpm -ivh


Em seguida é necessário editar o ficheiro /etc/profile e
acrescentar o seguinte (substituir 11.1.0.1 pela versão dos pacotes que instalaram):

export LD_LIBRARY_PATH=/usr/lib/oracle/11.1.0.1/client/lib
export TNS_ADMIN=/etc/oracle

e carregar a alteração do mesmo através do comando:

source /etc/profile

Depois é necessário criar a directoria /etc/oracle e dentro desta o ficheiro tnsnames.ora com um conteúdo semelhante ao seguinte (mas vai sempre depender da implementação Oracle, o melhor será que peçam ao responsável do Oracle um ficheiro tnsnames.ora já existe noutra máquina que seja cliente habitual do Oracle, mesmo que em ambiente Windows):

LIGACAODB =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = [endereço de rede do servidor ORACLE])(PORT = [1525 ou porta_tcp_oracle]))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = [nome do serviço no ORACLE])
[OU ALTERNATIVAMENTE:]
(SSID = [nome do SSID no ORACLE])
)
)

Depois executa-se o configurador do odbc da oracle normalmente encontrado em

/usr/share/oracle/
11.1.0.1/client/odbc_update_ini.sh

que vai configurar os ficheiros /etc/odbcinst.ini e /etc/odbc.ini. Cuidado, se já tiverem estes ficheiros com dados definidos, este processo poderá apagá-los, apesar de tal não ter acontecido comigo.

Nota: Tal como anteriormente, o texto 11.1.0.1 deverá ser substituído pela versão dos pacotes que instalaram, caso seja diferente.

Depois é necessário verificar se a biblioteca no ficheiro /etc/odbcinst.ini aponta correctamente para a biblioteca de Oracle instalada, e configurar o ficheiro /etc/odbc.ini para ter a definição correcta do nome da base de dados conforme definido no ficheiro /etc/oracle/tnsnames.ora (neste caso seria LIGACAODB, mas o melhor é usarem se possível o mesmo nome da base de dados real para evitar mais problemas do que os que já naturalmente irão ter...) e definir o nome da DSN que irão utilizar na ligação ODBC a partir do PHP ou outra linguagem qualquer, pois isto vai funcionar para Mono, Python, Ruby, C++ ou outra linguagem qualquer com suporte a ODBC em Linux.

Ah, e não me perguntem por ligações JDBC, não mexo em Java nem com máscara, luvas de borracha e um pau de cinco metros...

Finalmente, é preciso muita coragem para testar a ligação, pois quase garantidamente vão gastar os restantes 95% do tempo a tentar que isto realmente funcione (thanks, Oracle ;-)

O método de teste mais fiável que encontrei é utilizando o sqlplus que já foi instalado através de RPM, pelo comando:

sqlplus utilizadorDB/passwordDB@endereco_rede_servidor_ORACLE/LIGACAODB

Nota: LIGACAODB deve ter o mesmo nome que foi definido no inicio do ficheiro /etc/oracle/tnsnames.ora.

Se a ligação funcionar, podem subsistir problemas com a parte ODBC, mas a partir daí o problema resume-se a verificar a configuração dos dois ficheiros de configuração relativos ao ODBC indicados acima. Se não funcionar... mais uma vez, paciência e coragem são importantes, assim como as mensagens de erro fornecidas pelo sqlplus.

Se utilizarem PHP4/5, recomendo vivamente a biblioteca ADOBD para ligações a base de dados, inclusivamente ODBC. Por outro lado, se usarem PHP5, *não* recomendo a utilização de PDO, seja para o que for...

Sem comentários: