Como utilizar PDO no PHP para abstrair o acesso ao banco

Banco de Dados

Como utilizar PDO no PHP para abstrair o acesso ao banco

Atenção! Essa postagem foi escrita há mais de 2 anos. Na informática tudo evolui muito rápido e algumas informações podem estar desatualizadas. Embora o conteúdo possa continuar relevante, lembre-se de levar em conta a data de publicação enquanto estiver lendo. Caso tenha sugestões para atualizá-la, não deixe de comentar!

PDO (PHP Data Object) é uma extensão do PHP que permite realizar a abstração da camada de acesso ao banco de dados na sua aplicação. A documentação completa você pode acessar aqui.

Utilizando PDO você pode realizar consultas SQL em um tipo de SGBD (MySQL, por exemplo) e, simplesmente alterando o nome do driver utilizado, fazer com que sua aplicação passe a se comunicar com outro SGBD (PostgreSQL, por exemplo).

Instanciando a PDO

O primeiro passo para utilizar a PDO é instanciar o objeto. Neste exemplo vamos utilizar o driver do MySQL. localhost indica o endereço do SGBD.

$conex = new PDO('mysql:host=localhost;dbname=nome_do_banco', 'usuario', 'senha'); 

Substitua mysql pelo nome do driver que você vai utilizar. Alguns exemplos são pgsql (PostgreSQL), oci (Oracle) e sqlite (SQLite). Você pode visualizar a lista dos drivers da PDO neste link.

Buscando dados

Depois que você já possui o objeto da PDO rodando na variável $conex, é possível executar comandos no banco.

Para realizar uma consulta simples de dois campos existentes na tabela cadastros, faremos o seguinte comando:

$dados = $conex->query('SELECT nome, email FROM cadastros');
while ($linha = $dados->fetch(PDO::FETCH_OBJ)) {
  echo $linha->nome . ' - ' . $linha->email;
  echo '<br>';
}

Utilizando a variável $conex para realizar uma consulta no banco por meio do método query.

Depois a repetição se encarrega de receber os valores, atribuí-los à variável $linha. Fazemos isso utilizando o método fetch.

Repare que utilizei uma constante da classe PDO chamada PDO::FETCH_OBJ. Isso indica para a PDO que precisamos retornar os dados em formato de objeto. Você poderia utilizar outras opções como PDO::FETCH_ASSOC para retornar em formato de array associativo.

Procurando valores de maneira segura

Sempre que for inserir dados em uma consulta é necessário filtrá-los. Isso irá aumentar a segurança da sua aplicação. Não insira os dados diretamente na consulta pois poderá criar vulnerabilidades no código.

Em vez disso prefira os Prepared Statements, uma espécie de “consulta compilada” que aumenta a segurança do seu banco. Você irá indicar os locais onde os dados serão colocados e a PDO se preocupa com a filtragem deles.

Supondo que você está recebendo um número de identificação pelo GET, vamos buscá-lo e colocá-lo na consulta sem nenhuma filtragem prévia – a própria PDO fará isso.

$id = $_GET['id'];

$dados = $conex->prepare('SELECT nome, email FROM cadastros WHERE id = ?');
$dados->bindParam(1, $id);

$dados->execute();

if ($dados->rowCount() > 0) {
  $linha = $dados->fetch(PDO::FETCH_OBJ);
  echo 'Nome: ' . $linha->nome;
}

Esse exemplo é um pouco diferente. Recebemos o valor do GET e guardamos em uma variável. A consulta é preparada com um ?. Isso indica para a PDO que ali haverá algum valor.

Em seguida chamamos o método bindParam. O primeiro valor é o número do parâmetro – como só temos um, utilizamos 1. Caso haja mais de uma, você deverá especificar em que ordem ele aparece (1, 2, 3…). O segundo valor é o próprio conteúdo que será posto no espaço reservado. Não precisa se preocupar com aspas, validação de SQL Injection, escapar caracteres etc. A classe faz tudo isso.

Depois rodamos o método execute() e a consulta é enviada para o banco. Logo em seguida só fazemos algumas verificações e apresentamos os dados na tela. Cabe a você adaptar o código a suas necessidades.

Inserindo dados no banco

Para gravar dados no banco, você pode utilizar a mesma maneira que usamos na consulta.

$dados = $conex->prepare('INSERT INTO cadastros (nome, email) VALUES (?, ?)');

$dados->bindParam(1, $variavel_com_nome);
$dados->bindParam(2, $variavel_com_email);

$dados->execute();

Novamente não é preciso se preocupar com injeção de código ou com qualquer filtragem – tudo já está embutido na classe.

Você também pode nomear os parâmetros (utilizei um placeholder chamado abacaxi pra demonstrar que você pode utilizar qualquer string):

$dados = $conex->prepare('INSERT INTO cadastros (nome, email) VALUES (:nome, :abacaxi)');

$dados->bindParam(':nome', $variavel_com_nome);
$dados->bindParam(':abacaxi', $variavel_com_email);

$dados->execute();

Para que a classe não trate tudo como string, você pode também adicionar o tipo do dado que está sendo inserido para deixar sua validação ainda mais segura.

$dados = $conex->prepare('INSERT INTO cadastros (nome, idade) VALUES (:nome, :idade)');

$dados->bindParam(':nome', $variavel_com_nome, PDO::PARAM_STR);
$dados->bindParam(':idade', $variavel_com_idade, PDO::PARAM_INT);

$dados->execute();

Atualizando e removendo dados

A essa altura você já deve ter entendido como a PDO funciona. De qualquer maneira, vou deixar aqui dois exemplos em que você pode se basear para realizar UPDATEDELETE.

UPDATE

$consulta = $conex->prepare('UPDATE cadastros SET nome = ? WHERE id = ?');
$consulta->bindParam(1, $variavel_com_nome);
$consulta->bindParam(2, $id);
if ($consulta->execute()) {
  echo 'Dados atualizados com sucesso!';
}

DELETE

$consulta = $conex->prepare('DELETE FROM cadastros WHERE id = ?');
$consulta->bindParam(1, $id);
if ($consulta->execute()) {
  echo 'Dados removidos com sucesso!';
}

Considerações

Espero que tenham gostado e  que a utilização dessa biblioteca possa ser bastante útil nos projetos que vocês vão desenvolver.

Lembrando que a biblioteca precisa estar ativa e com os drivers necessários instalados (verifique no phpinfo()).

Também é importante lembrar que os comandos específicos de cada SGBD não podem ser utilizados, já que a PDO é uma camada de abstração.

Dúvidas, sugestões e tudo mais, não deixem de comentar aqui em baixo!

Um abraço a todos e fiquem com Deus.
Rafael Jaques