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/









