Você está na página 1de 4

Desmistificando o PDO - PHP Data Object

criado por Rubens Takiguti Ribeiro em 16/12/2009 12:38am


O que PDO?

PDO (PHP Data Objects) um mdulo de PHP montado sob o paradigma
Orientado a Objetos e cujo objetivo prover uma padronizao da forma
com que PHP se comunica com um banco de dados relacional. Este mdulo
surgiu a partir da verso 5 de PHP. PDO, portanto, uma interface que
define um conjunto de classes e a assinatura dos mtodos de comunicao
com uma base de dados.

Cada sistema gerenciador de bancos de dados (SGBD) pode prover um
driver para PDO. Apesar de PDO definir a assinatura dos mtodos que cada
driver deve implementar, alguns recursos podem no ser suportados. Logo,
a chamada a um mtodo pode ser "intil" dependendo do driver utilizado ou
da verso/modelo do servidor de Banco de Dados. Por exemplo,
algumas engines do SGBD MySQL no do suporte a transaes, logo, o
mtodo "beginTransaction" (responsvel por iniciar uma transao)
simplesmente no ter efeito sob tais condies.

Ao contrrio do que algumas pessoas pensam, PDO no uma camada de
abstrao de SQL. Cada SGBD relacional possui uma sintaxe prpria para
construo de SQL. Embora muitos deles se aproximem da especificao da
SQL-92, algumas diferenas existem. Portanto, usar PDO no significa que
seu sistema ser portvel entre diferentes SGBDs. Significa apenas que
voc se comunicar com uma base de dados atravs de um conjunto
determinado de mtodos e classes.

Observao
Criar uma camada da aplicao para abstrao de SQL extremamente
complexo. Vrias variveis devem ser levadas em conta e, possivelmente,
preciso abrir mo de muitos recuros especficos. Portanto, existem duas
linhas de desenvolvimento: uma defende a utilizao de um nico tipo de
SGBD por aplicao, para que os recursos especficos sejam utilizados ao
mximo e de forma otimizada, enquanto outra defende a generalizao e o
suporte a diferentes bases de dados, tornando o sistema mais portvel.
Tudo depende do objetivo da aplicao.

Por que usar PDO?

Antes da chegada de PDO, a linguagem PHP oferecia suporte comunicao com diferentes modelos de SGBD
atravs de mdulos especficos. A maioria deles provia uma biblioteca de funes e utilizava um resource para
representar a conexo e outro para representar um resultset (o resultado de uma consulta). As operaes eram
feitas sobre as variveis de resource.

Cada driver implementava suas operaes conforme imaginavam ser mais adequados. Embora alguns deles
tivessem um funcionamento semelhante, a ordem dos parmetros nem sempre era a mesma e podia causar
uma certa confuso entre programadores.

Quem j trabalhou com a biblioteca de funes de MySQL ou PostgreSQL, deve conhecer este funcionamento:

// MySQL
$c = mysql_connect('host', 'usuario', 'senha');
mysql_select_db('bd', $c);
mysql_set_charset('UTF8', $c);

$resultado = mysql_query('SELECT nome FROM usuarios', $c);
while ($obj = mysql_fetch_object($resultado)) {
echo $obj->nome;
}
mysql_free_result($resultado);
mysql_close($c);

// PostgreSQL
$c = pg_connect('host=host port=5432 dbname=bd user=usuario
password=senha');
pg_set_client_encoding($c, 'UNICODE');

$resultado = pg_query($c, 'SELECT nome FROM usuarios');
while ($obj = pg_fetch_object($resultado)) {
echo $obj->nome;
}
pg_free_result($resultado);
pg_close($c);

Note que a forma de conexo feita atravs de estratgias diferentes: MySQL passava os dados de conexo
atravs de parmetros, j o PostgreSQL utilizava uma string de conexo (com vrios dados), que uma
alternativa mais extensvel. Observe, ainda, que MySQL costuma receber o resource de conexo como ltimo
parmetro de suas funes, enquanto o PostgreSQL costuma receber o resource como primeiro parmetro.

PDO juntou o que havia de melhor em cada driver e gerou uma especificao. Embora a especificao no
trabalhe com resource explicitamente, ela define duas classes com significados semelhantes: PDO (que
representa uma conexo) e PDOStatement (que representa uma consulta/resultado). Alm destas, existe a
classe PDOException, que disparada por alguns mtodos para que seja realizado o tratamento de excees.

Utilizar PDO tende a ser mais simples do que utilizar biblioteca de funes, mas continua exigindo
conhecimento da sintaxe SQL especfica do modelo de SGBD envolvido. Embora muitos programadores ainda
utilizam as funes de conexo, existe a promessa de que PDO ser o padro de conexo em PHP 6, enquanto
as bibliotecas de funes passaro a ser extenses PECL, precisando ser instaladas a parte.
Como utilizar PDO?

Para utilizar PDO, primeiro instanciado um objeto da classe PDO, que representa a conexo com um banco.
No construtor da classe, deve ser informado o chamado "DSN", que uma string de conexo semelhante
quela vista anteriormente na funo de conexo com PostgreSQL. Cada driver PDO especifica uma forma de
como montado o DSN para o SGBD correspondente. Alm do DSN, tambm informado, por parmetro, o
usurio, a senha de acesso e as opes adicionais.

// Exemplo de conexao com MySQL via PDO
$dsn = 'mysql:host=host;port=3306;dbname=bd';
$usuario = 'usuario';
$senha = 'senha';
$opcoes = array(
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_CASE => PDO::CASE_LOWER
);

try {
$pdo = new PDO($dsn, $usuario, $senha, $opcoes);
} catch (PDOException $e) {
echo 'Erro: '.$e->getMessage();
}

Aps abrir uma conexo, as consultas podem ser feitas de duas maneiras:
1 - Atravs da prpria conexo, com o mtodo "exec" ou o "query";
2 - Montando uma prepared statement com o mtodo "prepare", que devolve um objeto da classe
PDOStatement, e depois executando o mtodo "execute" (desta classe).

O mtodo "query" utilizado para consultas que retornam resultados tabulares (como o SELECT) e devolve um
objeto da classe PDOStatement com o resultado. J o mtodo "exec" utilizado para consultas que no
retornam resultados tabulares (como o INSERT, UPDATE, DELETE) e retorna apenas o nmero de linhas
afetadas.

Estes mtodos so teis para executar consultas fixas (no-variveis). Afinal, se envolvessem valores recebidos
do usurio, estes valores precisariam ser escapados atravs do mtodo "quote" (para evitar falhas de
segurana com SQL Injection).

J o mtodo "prepare" til para montar uma consulta com dados variveis. possvel especificar uma SQL
com pontos de substituio que, ao serem substituidos, so escapados pela classe automaticamente. Vejamos
alguns exemplos:

// Usando "exec"
$inseriu = $pdo->exec('INSERT INTO logs (operacao) VALUES (1)');
$ultimo_id = $pdo->lastInsertId();

// Usando "query"
$stmt = $pdo->query('SELECT nome, login FROM usuarios');

// Percorrento um resultset com while
while ($obj = $stmt->fetchObject()) {
...
}

// Percorrendo um resultset com foreach
foreach ($stmt as $linha) {
...
}

Note que a classe PDOStatement (objeto $stmt) implementa a interface Traversable, indicando que ela pode
ser percorrida por uma estrutura "foreach".

Existem diferentes formas de se executar uma prepared statement com PDO:
// 1 - Usando "?" nos pontos-chave
$stmt = $pdo->prepare('INSERT INTO usuarios (nome, login) VALUES
(?,?)');

// Passando os valores a serem usados no primeiro e segundo "?"
$dados = array('Rubens', 'rubens');
$consultou = $stmt->execute($dados);

// 2 - Usando pontos-chave nomeados
$stmt = $pdo->prepare('INSERT INTO usuarios (nome, login) VALUES
(:nome, :login)');

// Passando os valores a serem usados em :nome e :login
array(':nome' => 'Rubens', ':login' => 'rubens');
$consultou = $stmt->execute($dados);

// 3 - Fazendo binding de parametros
$stmt = $pdo->prepare('INSERT INTO usuarios (nome, login) VALUES
(:nome, :login)');

// Fazendo o binding
$nome = 'Rubens';
$login = 'rubens';
$stmt->bindParam(':nome', $nome, PDO::PARAM_STR, 128);
$stmt->bindParam(':login', $login, PDO::PARAM_STR, 20);

// Executando a SQL com os valores definidos com binding
$consultou = $stmt->execute();

Prepared statements tendem a ser mais rpidas que as consultas convensionais, j que a consulta fica
previamente "compilada" e pronta para execuo com novos valores. Ao invs do SGBD interpretar toda a SQL,
ele apenas atribui novos valores aos pontos chave e realiza a operao. Funcionalidade muito til para
inseres ou atualizaes em massa em uma tabela.
Outros benefcios

1 - Obteno padronizada de erros ocorridos em consultas, atravs do mtodo "errorInfo" e "errorCode" da
classe PDO e PDOStatement.

2 - Suporte a inicializao e encerramento de transaes de forma padronizada (esta funcionalidade depende
do suporte do SGBD), atravs dos mtodos "beginTransaction", "commit" e "rollBack".

3 - Suporte para trabalhar com handle de arquivos para realizar inseres ou consultas a grandes volumes de
dados, para economizar memria. Isso acontece pois a prpria classe PDO fica responsvel por transmitir o
arquivo "aos poucos", sem precisar carreg-lo inteiramente na memria, como seria feito da forma tradicional.
Um handle de arquivo utiliza uma varivel do tipo resource, que funciona como um "ponteiro" para o arquivo.
Concluso

O objetivo deste artigo motivar programadores a utilizar PDO. Nota-se que muitos programadores ainda no
utilizam PDO pois j esto acostumados com as antigas bibliotecas de funes de conexo e no mudam por
comodidade.

Porm, deve-se atentar ao futuro de PHP, que est caminhando cada vez mais para o paradigma orientado a
objetos. Neste futuro, que j presente, est inserido o PDO.

Você também pode gostar