PDO (PHP Data Object) é um módulo nativo desenvolvido a partir do PHP 5 que tem como objetivo fornecer uma estrutura que facilita a integração de aplicações desenvolvidas sob o paradigma de orientação à objetos com bancos de dados relacionais de forma fácil e sem a necessidade de alterar a padronização do sistema.
Com o PDO é possível desenvolver aplicações mais seguras a nível de banco de dados. Dentre as funcionalidades que ele nos oferece podemos destacar o controle de transações e o uso de prepared statements.
Para ativar o módulo PDO no seu php basta ir ao arquivo de configuração php.ini, localizar as linhas php_pdo.dll e php_pdo_mysql.dll e descomentá-las (retirar o ponto e viírgula “;” do início da linha ) . Nesse caso estaríamos aptos a utilizar PDO com MySQL. Se você utiliza outro SGBD, basta descomentar a linha referente à ele. Feito isso reinicie o seu servidor de aplicações.
Conexão com o banco de dados utilizando PDO
Bom. Veremos agora como utilizar o PDO, conectar com bancos de dados, executar querys e etc.
Veja como se conectar com um banco de dados via PDO:
1 2 3 4 5 | <?php $pdo = new PDO("mysql:host=localhost;dbname=nome_banco", "root", "sua_senha"); if(!$pdo){ die('Erro ao criar a conexão'); } |
Tarefa simples. Basta informar o sgbd que será utilizado (mysql, mssql, pgsql, firebird, etc), o host, o nome do banco de dados, o usuário e a senha.
Já na conexão com o banco de dados já temos a nossa primeira vantagem com relação à utlização de PDO. Se a aplicação estiver com umas 20 tabelas e umas 200 queryes de manipulação e recuperação de dados e for necessário mudar de SGBD por qualquer motivo, basta alterar os parâmetros de conexão e pronto!!! Sem a utilização de PDO talvez fosse necessário sair procurando todos os mysql_query e alterar por pg_query ou msql_query.
Executar querys no banco de dados
Vamos a um exemplo agora de como executar querys via PDO no nosso banco de dados.
Primeiro uma query de inserção de dados.
6 7 8 9 10 11 12 | $executa = $pdo->query("INSERT INTO cliente(idcliente, nome) VALUES ('1', 'Rafael')"); if($executa){ echo 'Dados inseridos com sucesso!'; } else{ print_r($pdo->errorInfo()); } |
Agora um select:
15 16 17 18 19 20 21 22 23 | $rs = $pdo->query("SELECT idcliente, nome FROM cliente")->fetchAll(); if(!$rs){ print_r($pdo->errorInfo()); } foreach ($rs as $reg){ echo 'Código: ' . $reg['idcliente'] . '<br />'; echo 'Nome: ' . $reg['nome'] . '<br /><br />'; } |
Nesse exemplo ele me retorna em forma de array todos os resultados gerados pela consulta. Com isto basta percorrer o array e exibir as informações.
Utilizar prepared statements e bind params
Prepared Statemens são consultas pré-preparadas onde dividimos em partes a inserção do código SQL a ser executado e os valores a serem utilizados (bind params). Com os prepareds statements utilizamos na query os marcadores de lugar e depois informamos quais serão os valores que deverão ser utilizados em cada um dos lugares. Isso fornece mais segurança ao nosso banco de dados e nos previne de ações maliciosas como o SQL Injection.
Temos duas formas de utilizar essa técnica. Primeiro através dos pontos de interrogação ou então através de pseudo-nomes que funcionam como variáveis.
Veja:
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | $idcliente = 100; $nome = "Rafael Wendel Pinheiro"; try{ $stmte = $pdo->prepare("INSERT INTO cliente(idcliente, nome) VALUES (?, ?)"); $stmte->bindParam(1, $idcliente , PDO::PARAM_INT); $stmte->bindParam(2, $nome , PDO::PARAM_STR); $executa = $stmte->execute(); if($executa){ echo 'Dados inseridos com sucesso'; } else{ echo 'Erro ao inserir os dados'; } } catch(PDOException $e){ echo $e->getMessage(); } |
Preparamos a query e substituimos os valores pelo ponto de interrogação (?). Depois, obedecendo a ordem dos pontos, colocamos cada valor e o tipo de dado daquele atributo.
A outra forma:
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | $idcliente = 100; $nome = "Rafael Wendel Pinheiro"; try{ $stmte = $pdo->prepare("INSERT INTO cliente(idcliente, nome) VALUES (:idcliente, :nome)"); $stmte->bindParam(":idcliente", $idcliente , PDO::PARAM_INT); $stmte->bindParam(":nome", $nome , PDO::PARAM_STR); $executa = $stmte->execute(); if($executa){ echo 'Dados inseridos com sucesso'; } else{ echo 'Erro ao inserir os dados'; } } catch(PDOException $e){ echo $e->getMessage(); } |
Nesse caso informamos o nome do parâmetro que utilizamos na query e também o valor e tipo de dado que ele deve receber.
Para finalizar vamos ver um exemplo onde o resultado da nossa query nos retorna os obejtos de cada resultado da consulta SQL (seria o equivalente ao mysql_fetch_object).
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | $nome = "Rafael Wendel Pinheiro"; try{ $stmte = $pdo->prepare("SELECT idcliente, nome FROM cliente WHERE nome = ?"); $stmte->bindParam(1, $nome , PDO::PARAM_STR); $executa = $stmte->execute(); if($executa){ while($reg = $stmte->fetch(PDO::FETCH_OBJ)){ /* Para recuperar um ARRAY utilize PDO::FETCH_ASSOC */ echo 'Código: ' . $reg->idcliente . '<br />'; echo 'Nome: ' . $reg->nome . '<br /><br />'; } } else{ echo 'Erro ao inserir os dados'; } } catch(PDOException $e){ echo $e->getMessage(); } |
E é isso. Em breve escreverei um post mostrando como utilizar o controle de transações com PDO.
Qualquer dúvida utilize a caixa de comentários.
Abs
Siga-me no twitter: @rafaelwendel
Excelente, esse post aqui também é bom http://blog.glaucocustodio.com/2012/08/04/usando-pdo-do-php/
Muito bom! Valeu meu caro, estou começando a usar o PDO a pouco tempo, e realmente poupa muito, mas muito trabalho.
Excelente tutorial!
Comecei a estudar PDO e esse artigo ajudou bastante.
Obrigado!
Ótimo post!
Estou iniciando em PDO e gostaria de fazer duas perguntas:
1) Qualquer aplicação, por mais simples que seja, pode ser em PDO?
2) E para as grades aplicações é possível fazer JOINs e grandes consultas, por exemplo, com SELECT dentro de SELECT?
Valeu.
Olá Julio,
É recomendável que se utilize PDO em qualquer tipo de projeto, desde os pequenos até os de grande porte. E isso se deve à segurança que ele proporciona e a padronização quanto ao acesso aos dados. E tudo que é possível fazer com o SQL puro é possível fazer com o PDO. Desde consultas extremamente simples até àquelas que envolvam inúmeras junções e até “selects” aninhados.
Abs!
Opa!
Vou me aprofundar mais neste assunto então.
Abs!
Rafael, como deixar esses métodos de INSERT, UPDATE, DELETE e SELECT dinâmicos, ou seja, que possam ser utilizados para qualquer tabela? Passar o nome da tabela e os campos por parâmetro. Segue um exemplo de UPDATE:
// UPDATE GENÉRICO
function atualizar($tabela, $id, $dados) {
// UPDATE filmes SET filme = ‘filme1′, preco = ’80’ WHERE id = 85
$pdo = conectar();
$sql = “UPDATE $tabela SET “;
$filmes = new ArrayIterator($dados)
while($filmes->valid()):
$sql. = $filmes->key(). ” = ? ,”;
$filmes->next;
endwhile;
//$sql = substr($sql, 0, -1);
$sql2 = rtrim($sql, ‘,’);
$sql2.= ” WHERE id = ?”;
$atualizar = $pdo -> prepare($sql2);
$i = 1;
foreach($dados as $valor)
$atualizar->bindValue($i, $valor);
$i++;
endforeach;
echo $sql;
$atualizar->bindValue($i, $id);
$atualizar -> execute();
}
Gostaria de fazer para os demais métodos. Poderia me ajudar?
Fred,
Já deu uma olhada nas video-aulas de Doctrine? (http://www.rafaelwendel.com/categoria/doctrine).
Qualquer coisa me mande um email que eu desenvolvi uma classe que tem insert, update e delete genérico.
Abs!
Cara, caiu PDO nas duas provas do TRF-4 ontem. Como é difícil lembrar de detalhes de algo que nunca se usa.. rs.. O PDO é muito importante, mas eu precisarei reformar todas as minhas queries para implementá-lo. Enfim, seja o que Deus quiser… rs.. Obrigado por este simples e direto artigo.
Depois de ver em vários site, este é o que melhor explica, parabéns. Só uma dúvida, na parte do código onde se utiliza o comando sql “SELECT”, na parte de consulta, caso não exista o nome no bd não está mostrando a mensagem que deveria mostrar: else { echo ‘Erro ao inserir os dados’;/*aqui a mensagem correta deveria erro ao consultar.. */ }
um dos erros da informação é a falta de um exemplo prático – por exemplo quando informar a senha está digitado “senha” o certo seria por exemplo digitar “123456” – por exemplo – o nome também usar o nome de quem informa para exemplo –
Olá Aurelino,
Obrigado pela dica!
Abs!
Eu queria poder fazer um update através de um select mais não estou conseguindo alguem me ajuda
exec( “INSERT logistica (`cliente_id`) SELECT id FROM cliente”);
$db->exec(“UPDATE `starvisa`.`logistica` SET `data`=’$_POST[data]’, `saida_visito`=’$_POST[saida_visito]’ WHERE id=$_POST[test] “);
?>
Rafael, preciso fechar as conexoes? Como fecho corretamente?
Junior,
Só setar null à variável da conexão.
Abs!
Olá Rafael, muito bom o artigo. Consegui entender bem os seus exemplos, além disso, fui mais além e, com o Netbeans, desenvolvi um formulário onde os dados forma enviados para serem manipulados pelas queryes com uso do prepared statements e bind params e inseridos com sucesso no banco.
Gostaria de, assim como os demais colegas, lhe pedir para postar algum exemplo de crude onde pudéssemos aprender e aprimorar um pouco mais os recursos do PDO.
Valeu!
Cara estou tentando utilizar dois whiles para criar uma paginação com PDO mas não vai de jeito nenhum.
$pesquisa_livro = $pdo->prepare(“SELECT * FROM livro_receita WHERE id_usuario = ? LIMIT $inicio,$maximo”);
$pesquisa_livro->bindParam(1, $id_user , PDO::PARAM_STR);
$executa = $pesquisa_livro->execute();
while($registro_livro = $pesquisa_livro->fetch(PDO::FETCH_OBJ)){
$livro_receita_id = $registro_livro->id_receita;
$pesquisa_receita_livro = $pdo->prepare(“SELECT * FROM receitas WHERE id = ? LIMIT $inicio,$maximo”);
$pesquisa_receita_livro->bindParam(1, $livro_receita_id , PDO::PARAM_STR);
$executa = $pesquisa_receita_livro->execute();
while($resultado_pesquisa = $pesquisa_receita_livro->fetch(PDO::FETCH_OBJ)){
$pesquisa_titulo = $resultado_pesquisa->nome_receita;
echo ‘$pesquisa_titulo‘;
}}
Não consigo recuperar os registros quando utilizo os dois whiles.
Alguma sugestão?
Celio,
Quando você testa com apenas 1 while dá certo a recuperação dos dados? Aparece alguma mensagem de erro?
Abs!