Subscribe to ACAlbuquerque.BlogRSS

Abstração de SGBD no PHP – PEAR::MDB2

Em 26/10/2009 by acalbuquerque  
categorizado em Destaques, PHP, Tecnologia

As conexões com um banco de dados SQL estão presentes em quase 100% das páginas que utilizam algum tipo de BD, mas o grande problema é que nem sempre quem escreve esses scripts sabem fazê-las de forma segura e sustentável.

Pensando nisso, um grupo de programadores do *PEAR decidiu criar um package (uma classe) que melhorasse as conexões SQL e ao mesmo tempo fosse compatível e fácil de ser usado em diversos tipos de bancos de dados, assim surgiu o package PEAR::DB que evoluiu para o PEAR::MDB2.

Se você utiliza uma versão do PHP5+ ou um servidor recente, é muito provável que já tenha tanto o PEAR como o pacote MDB2 instalados. Caso não, pesquise no google como instalar o pear e a mdb2, pois existem muitos resultados falando já sobre isso.

*PEAR é um repositório de packages (classes) PHP criado e mantido por centenas de programadores, com o intuito de criar e melhorar a usabilidade do PHP. Eles disponibilizam diversos pacotes que estão em constantes melhorias e cada qual com uma utilidade mais incrível que o outro.
Tamanhas são as utilidades dos pacotes PEAR que as versões mais novas do PHP já são distribuídas com o PEAR e seus pacotes mais usados já instalados.

Mais informações no site www.pear.php.net

- Conexão

A primeira coisa a se observar, é que para podermos usar um package da PEAR é necessário dar um include no arquivo principal deste, no nosso caso, devemos adicionar o arquivo MDB2.php no início de tudo (não é necessária a especificação do caminho):

require_once('MDB2.php');

- Declaração da DSN

Feito isso, devemos nos conectar ao banco de dados. As conexões dos packages da PEAR (DB e MDB2) seguem uma sintaxe um pouco diferente da comumente utilizada pelos famosos mysql_connect, ou pg_connect, etc. Começando por uma DSN, que é uma string que possui uma forma especifica de declaração, englobando os dados da conexão:

phptype://usuario:password@host/database

onde:
phptype = Tipo de DB{
fbsql: FrontBase
ibase: InterBase
mssql: Microsoft SQL Server
mysql: MySQL
mysqli: MySQL Improved
oci8 : Oracle 7/8/9
pgsql: PostgreSQL
querysim: QuerySim
sqlite: SQLite
}
usuario = nome de usuário
password = senha
host = host
database = nome do DB

- Conectando

Declarada a DSN, falta chamar o método de conexão, existem três:

- connect : Era mais usado no package PEAR:biggrin.gifB, mas caiu em desuso com o MDB2 (mas preservado).
- singleton : É usado para evitar que se sejam criadas duas conexões com a mesma DSN. Caso já haja alguma, ele retonará um erro.
- factory : É o mais utilizado e recomendado para a maioria das tarefas

*obs: Para chamá-los devemos precedê-los de MDB2:: e usar como argumento a DSN:
$con =& MDB2::factory($dsn);

ATENÇÃO!

Para que o uso do MDB2 funcione corretamente é necessário o uso de um objeto-referência do objeto original em vez de uma cópia:

  • $con =& MDB2::factory($dsn);

e NÃO

  • $con = MDB2::factory($dsn);

- Recuperando dados

Para recuperarmos dados da DB (SELECT, SHOW, EXPLAIN, etc) utilizamos o método query().
Ele deve ser chamado através do objeto da conexão:

$result =& $con->query($sql_query);

Será retornado um handler para o resultado, e através dele podem ser usados outros métodos (atente novamente para o uso de referências – &).

$result =& $con->query('SELECT * FROM table WHERE column=1');
//ou
$select = 'SELECT * FROM table WHERE column=1';
$result =& $con->query($select);

Número de linhas Retornadas

Para verificar o número de linhas retornadas devemos usar o método numRows() do objeto-resultado.

$rows = $result->numRows();

Retirando dados do objeto-resultado

Após realizada a query, devemos chamar outro método caso desejemos usar os dados retornados: o fetchRow().
Este método aceita como parâmetro a forma como o resultado deve ser retornado, existem três tipos:

- MDB2_FETCHMODE_ORDERED

Modo padrão, retorna uma array em que cada chave numérica corresponde á coluna mais á esquerda, em ordem crescente e começando pelo 0.

$row =& $result->fetchRow(MDB2_FETCHMODE_ORDERED);

//Resultado:

Array
(
 [0] => Valor1
 [1] => 1
 [2] => Valor3
)

- MDB2_FETCHMODE_ASSOC

Esse modo retorna uma array em que cada chave é o nome da coluna correspondente.

$row =& $result->fetchRow(MDB2_FETCHMODE_ASSOC);

//Resultado:

Array
(
 [coluna1] => Valor1
 [coluna2] => 1
 [coluna3] => Valor3
)

- MDB2_FETCHMODE_OBJECT

-Esse modo retorna um objeto em que cada coluna é tratada como um atributo.

$row =& $result->fetchRow(MDB2_FETCHMODE_OBJECT);

//Resultado:

stdClass Object
(
 [coluna1] => Valor1
 [coluna2] => 1
 [coluna3] => Valor3

)

Alternativamente podemos configurar um FETCHMODE padrão para a conexão com que vamos trabalhar através do método setFetchMode(). Feito isso, caso chamemos, por exemplo, um fetchRow() (sem argumento), a forma retornada seria a indicada nesse método.

$con->setFetchMode(MDB2_FETCHMODE_ORDERED);
// ou
$con->setFetchMode(MDB2_FETCHMODE_ASSOC);
//ou
$con->setFetchMode(MDB2_FETCHMODE_OBJECT);

- Método fetchAll()

Esse método retorna uma array bidimensional contendo todas as linhas do objeto-resultado.

$row =& $result->fetchAll(MDB2_FETCHMODE_ASSOC);

//resultado

Array
(
 [0] => Array
 (
 [coluna1] => Valor1
 [coluna2] => 1
 [coluna3] => Valor3
 )

 [1] => Array
 (
 [coluna1] => V1
 [coluna2] => 2
 [coluna3] => V3
 )

)

Uma maneira mais rápida e prática e fazer isso tudo seria o uso do método queryAll() = query()+fetchAll()

$row =& $con->queryAll("SELECT * FROM test", MDB2_FETCHMODE_ASSOC);

Executando Query´s

Para executar query de manipulação de dados (INSERT, UPDATE, DELETE), não deve ser o usado o método query() e sim o exec()
Esse método retornará um erro caso seja usado com queries que não sejam DMQs, como SELECT.

$sql ="INSERT INTO test(coluna1, coluna2, coluna3) VALUES ('v_col1', 3, 'v_col3')"

$nrows =& $con->exec($sql);

Tratamento de erros

Para evitar problemas tanto no código como de segurança, deve-se sempre fazer uma verificação se a ação não resultou em um erro, para tanto usamos o método PEAR::isError($objeto->resultado).
Verificado que existe um erro, podemos obter a mensagem enviada pelo MDB2 através do método getMessage()


$result =& $cnt->query("SELECT * FROM tabela_inexistente");
if(PEAR::isError($result)) { die($result->getMessage()); }

Referências:

Oficial da PEAR: www.pear.php.net/manual/en/package.database.mdb2.php

CODESCHMIE: codeschmie.de/archives/127-MDB2-Cheatsheet.html

phpied http://www.phpied.com/