Vous êtes sur la page 1sur 5

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 módulo de PHP montado sob o paradigma


Orientado a Objetos e cujo objetivo é prover uma padronização da forma
com que PHP se comunica com um banco de dados relacional. Este módulo
surgiu a partir da versão 5 de PHP. PDO, portanto, é uma interface que
define um conjunto de classes e a assinatura dos métodos de comunicação
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 métodos que cada
driver deve implementar, alguns recursos podem não ser suportados. Logo,
a chamada a um método pode ser "inútil" dependendo do driver utilizado ou
da versão/modelo do servidor de Banco de Dados. Por exemplo, algumas
engines do SGBD MySQL não dão suporte a transações, logo, o método
"beginTransaction" (responsável por iniciar uma transação) simplesmente
não terá efeito sob tais condições.

Ao contrário do que algumas pessoas pensam, PDO não é uma camada de


abstração de SQL. Cada SGBD relacional possui uma sintaxe própria para
construção de SQL. Embora muitos deles se aproximem da especificação da
SQL-92, algumas diferenças existem. Portanto, usar PDO não significa que
seu sistema será portável entre diferentes SGBDs. Significa apenas que
você se comunicará com uma base de dados através de um conjunto
determinado de métodos e classes.

Observação
Criar uma camada da aplicação para abstração de SQL é extremamente
complexo. Várias variáveis devem ser levadas em conta e, possivelmente, é
preciso abrir mão de muitos recuros específicos. Portanto, existem duas
linhas de desenvolvimento: uma defende a utilização de um único tipo de
SGBD por aplicação, para que os recursos específicos sejam utilizados ao
máximo e de forma otimizada, enquanto outra defende a generalização e o
suporte a diferentes bases de dados, tornando o sistema mais portável.
Tudo depende do objetivo da aplicação.

Por que usar PDO?

Antes da chegada de PDO, a linguagem PHP oferecia suporte à comunicação


com diferentes modelos de SGBD através de módulos específicos. A maioria
deles provia uma biblioteca de funções e utilizava um resource para
representar a conexão e outro para representar um resultset (o resultado
de uma consulta). As operações eram feitas sobre as variáveis de resource.

Cada driver implementava suas operações conforme imaginavam ser mais


adequados. Embora alguns deles tivessem um funcionamento semelhante,
a ordem dos parâmetros nem sempre era a mesma e podia causar uma
certa confusão entre programadores.
Quem já trabalhou com a biblioteca de funções 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 conexão é feita através de estratégias diferentes:


MySQL passava os dados de conexão através de parâmetros, já o
PostgreSQL utilizava uma string de conexão (com vários dados), que é uma
alternativa mais extensível. Observe, ainda, que MySQL costuma receber o
resource de conexão como último parâmetro de suas funções, enquanto o
PostgreSQL costuma receber o resource como primeiro parâmetro.

PDO juntou o que havia de melhor em cada driver e gerou uma


especificação. Embora a especificação não trabalhe com resource
explicitamente, ela define duas classes com significados semelhantes: PDO
(que representa uma conexão) e PDOStatement (que representa uma
consulta/resultado). Além destas, existe a classe PDOException, que é
disparada por alguns métodos para que seja realizado o tratamento de
exceções.

Utilizar PDO tende a ser mais simples do que utilizar biblioteca de funções,
mas continua exigindo conhecimento da sintaxe SQL específica do modelo
de SGBD envolvido. Embora muitos programadores ainda utilizam as
funções de conexão, existe a promessa de que PDO será o padrão de
conexão em PHP 6, enquanto as bibliotecas de funções passarão a ser
extensões PECL, precisando ser instaladas a parte.
Como utilizar PDO?

Para utilizar PDO, primeiro é instanciado um objeto da classe PDO, que


representa a conexão com um banco. No construtor da classe, deve ser
informado o chamado "DSN", que é uma string de conexão semelhante
àquela vista anteriormente na função de conexão com PostgreSQL. Cada
driver PDO especifica uma forma de como é montado o DSN para o SGBD
correspondente. Além do DSN, também é informado, por parâmetro, o
usuário, a senha de acesso e as opções 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();
}

Após abrir uma conexão, as consultas podem ser feitas de duas maneiras:
1 - Através da própria conexão, com o método "exec" ou o "query";
2 - Montando uma prepared statement com o método "prepare", que
devolve um objeto da classe PDOStatement, e depois executando o método
"execute" (desta classe).

O método "query" é utilizado para consultas que retornam resultados


tabulares (como o SELECT) e devolve um objeto da classe PDOStatement
com o resultado. Já o método "exec" é utilizado para consultas que não
retornam resultados tabulares (como o INSERT, UPDATE, DELETE) e retorna
apenas o número de linhas afetadas.

Estes métodos são úteis para executar consultas fixas (não-variáveis).


Afinal, se envolvessem valores recebidos do usuário, estes valores
precisariam ser escapados através do método "quote" (para evitar falhas de
segurança com SQL Injection).

Já o método "prepare" é útil para montar uma consulta com dados


variáveis. É possível especificar uma SQL com pontos de substituição que,
ao serem substituidos, são 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 rápidas que as consultas


convensionais, já que a consulta fica previamente "compilada" e pronta
para execução com novos valores. Ao invés do SGBD interpretar toda a
SQL, ele apenas atribui novos valores aos pontos chave e realiza a
operação. Funcionalidade muito útil para inserções ou atualizações em
massa em uma tabela.

Outros benefícios

1 - Obtenção padronizada de erros ocorridos em consultas, através do


método "errorInfo" e "errorCode" da classe PDO e PDOStatement.

2 - Suporte a inicialização e encerramento de transações de forma


padronizada (esta funcionalidade depende do suporte do SGBD), através
dos métodos "beginTransaction", "commit" e "rollBack".

3 - Suporte para trabalhar com handle de arquivos para realizar inserções


ou consultas a grandes volumes de dados, para economizar memória. Isso
acontece pois a própria classe PDO fica responsável por transmitir o arquivo
"aos poucos", sem precisar carregá-lo inteiramente na memória, como seria
feito da forma tradicional. Um handle de arquivo utiliza uma variável do tipo
resource, que funciona como um "ponteiro" para o arquivo.

Conclusão

O objetivo deste artigo é motivar programadores a utilizar PDO. Nota-se


que muitos programadores ainda não utilizam PDO pois já estão
acostumados com as antigas bibliotecas de funções de conexão e não
mudam por comodidade.

Porém, 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.

http://digitalbush.com/projects/masked-input-plugin/
http://www.leonardonobre.com.br/?cat=10
http://www.adaptinsite.com/blog/css-dinamico-inserindo-php-no-css

Vous aimerez peut-être aussi