PDO - Introdução e conceitos

Uma introdução aos conceitos de utilização dessa extensão do PHP, que é uma forma nativa rápida e de fácil utilização de conectar a banco de dados, manipular e recuperar dados com métodos simples e poderosos.

[ Hits: 35.874 ]

Por: Adilson Santos da Rocha em 14/04/2008


Conetando e executando queries



Conectando-se a bases de dados:

Para conexão com a base de dados são necessários os parâmetros básicos, host, usuário, senha, nome do banco etc. Isto tanto para MySQL, PostgreSQL ou outros bancos.

A conexão se dá pela instância da classe PDO. Passando para seu __construct os parâmetros necessários para a conexão. Ex:

try {
   $db = new PDO("pgsql:host=localhost dbname=sistema user=postgres password=bananaamassada");
} catch (PDOException  $e) {
   print $e->getMessage();
}

A partir de agora a variável $db é um objeto PDO, e através dele pode-se executar vários métodos, trabalhar com transações, preparar e executar "queries", modificar alguns atributos da classe etc.

Um recurso muito interessante e útil da PDO é o tratamento de exceções, dessa forma a classe não retorna erros, mas sim gera exceções que são muito mais fáceis para tratar e debugar, para isto use o método setAttribute() para alterar o atributo PDO::ATTR_ERRMODE, que é a forma como a PDO vai trabalhar com os erros, o valor para esse atributo pode ser PDO::ERRMODE_EXCEPTION, que faz a PDO trabalhar com exceções como descrito acima:

$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

Também é possível trabalhar com conexões persistentes junto ao banco de dados. Para isto o atributo PDO::ATTR_PERSISTENT deve ser true, pode-se utilizar o atributo direto como parâmetro no momento da conexão ou utilizando o método setAttribute.

$db->setAttribute(PDO::ATTR_PERSISTENT,true);

Executando query

Uma vez conectado a base de dados podemos utilizar alguns dos métodos da PDO para executar nossas "queries", o próprio método "query" pode ser utilizado, porém opções como prepare e execute tornam seu uso muito mais flexível e inteligente.

A execução de uma query vai retornar um outro objeto o Statement. Objetos Statements são o resultado da execução ou da preparação para execução de uma query e provêem vários métodos para obter-se informações sobre a query e sua execução. Métodos para "fetch", pegar informações sobre as colunas, linhas entre outros. Recursos semelhantes com os que utiliza-se nas funções nativas mysql nas quais um resultset é passado como parâmetro, ex: mysql_num_rows($resultset).

Dando poder a suas queries

Normalmente a arte de compor queries exige um esforço grande em concatenar e "escapar" strings, formatar valores de acordo com o tipo do campo entre outros. Ex:

$sql="INSERT INTO produtos (produ_nome,grupo_id,categ_id,produ_detalhe,produ_fotos) VALUES ( ". addslashes("Teclado ABNT2 mobil 'T" )".",'2','1',addslashes($detalhe),"tec.png")";
$rs = $db->query($sql);

Essa query pode ser executada normalmente no mysql, mas em outros bancos pode ocorrer problemas com os campos grupo_id e categ_id, que são inteiros e estão entre apóstrofes. Além do programador ter que preocupar-se com o escape das strings e outros fatores.

Uma medida que ameniza e evita muitos problemas é o uso do método prepare da PDO. São os famosos prepared statements. Ex:

try {
    $res = $db->prepare(INSERT INTO produtos (produ_nome, grupo_id, categ_id, produ_detalhe, produ_fotos)  VALUES  (?, ?, ?, ?, ?);
   $valores = array("Teclado ABNT2 mobil 'T",2,1,$detalhe,'tec.png');
   $res->execute($valores);
} catch ( PDOException  $e) {
    print "Erro: Código:" . $e->getCode() . "Mensagem" . $e->getMessage();
}

Note que não houve nenhuma preocupação em cuidar de apóstrofes e nem se o valores são strings, inteiros ou real, apenas preparamos uma query para a execução e passamos 5 parâmetros "?" e logo em seguida a query é executada com o método execute onde um array com os valores na ordem dos campos a ser inseridos "?". Dessa forma a query funcionaria independente do banco, a PDO cuidaria do trabalho bruto de escape e blindagem dos dados. O programador preocupa-se apenas para que os dados seja enviados na ordem correta para o método execute.

O mesmo serve para outras instruções sql como Update e Selects.

Ainda há a possibilidade de utilizar nomes ao invés de "?" no método prepare, para isso deve-se utilizar o método bindParam para fazer a tradução do parâmetro (consulte a documentação desse método).

Recuperando dados

Com a técnica acima também facilita-se muito na recuperação de dados, uma vez que não há a necessidade de verificar tipos de dados escapes etc. Ex:

$sql = "SELECT * FROM produtos WHERE produ_id = ?";
try {
   $res  = $db->prepare($sql);
   $res->execute(array($produ_id));
} catch ( PDOException  $e) {
   print "Erro: Código:" . $e->getCode() . "Mensagem" . $e->getMessage();
}

Nesse caso $res é um objeto da classe Statement com métodos e atributos. Na maioria dos casos esse tipo de objeto nos desperta apenas alguns interesses, os dados retornados, o número de linhas e as colunas retornados.

Para acessar os dados retornados podemos utilizar o método fetch, fetchObjetc ou fetchAll. O método fetch retorna a linha ativa do statement na forma de um array onde os valores podem ser acessados pelo número da coluna iniciando em 0 (zero) ou o nome da coluna.

Um método muito poderoso é o fetchAll, que retorna um array indexado de 0 ao número de linhas retornadas, e cada item desse array é um outro array exatamente como o retornado pelo método fetch.

Enquanto que fetchObject retorna um objeto com a linha ativa do resultset tendo as colunas como propriedades.

Uma observação importante é que pode-se modificar o tipo de retorno dos métodos fetch e fetchAll passando o tipo de "fetch" desejado na chamada do método ou utilizando o método setFetchMode do statement.

Os valores mais utilizados são:
  • PDO::FETCH_ASSOC - faz com que seja retornada a linha ativa do resultset na forma de um array indexado pelas colunas retornadas;
  • PDO::FETCH_OBJ: - faz com que o retorno seja um objeto como o retornado em fetchObject.

Ainda existem outros métodos de fetch que podem ser utilizados, o PDO::FETCH_BOUND cria variáveis no php com os nomes da colunas da linha atual do resultset e PDO::FETCH_BOTH, que é o padrão de "fetch" do statements que retorna a linha atual como descrito no método fetch. Ex.:

$dado = $res->fetch(PDO::FETCH_ASSOC);
print_r($dado);

A saída seria:

Array(
  [produ_id] => 1
  [produ_nome] =>Teclado ABNT2 mbil 'T
  [grupo_id] => 2
  [categ_id] =>1
  [produ_detalhe] =>teclado ergométrico
  [produ_foto] =>tec.png
)

Para alterar o modo de fetch também podemos utilizar o método setFetchMode e passar como parâmetro o método de fetch a ser utilizado. Ex.:

$res->setFetchMode(PDO::FETCH_OBJ);
$dados = $res->fetchAll();

Nesse caso $dados seria um array indexado de 0 ao número de linhas do resultset e cada item do array é um objeto que tem as colunas como propriedades.

Página anterior     Próxima página

Páginas do artigo
   1. Introdução
   2. Conetando e executando queries
   3. Transações
Outros artigos deste autor

Engenharia de Software - Fazer melhor o software e fazer o software melhor

Aumente sua produção em PHP

Ninguém planeja fracassar, mas muitos fracassam por não planejar

Leitura recomendada

Armazenando datas de uma outra forma

Como criar um sistema de autenticação de usuários usando PHP/MySQL

Stored Procedures usando o MySQL e PHP

Oracle 9i, Apache e PHP

PHP com suporte ao MS SQL Server 7

  
Comentários
[1] Comentário enviado por edirlf em 14/04/2008 - 12:45h

Já está nos favoritos. Parabéns.

[2] Comentário enviado por ygorth em 14/04/2008 - 15:02h

Parabéns.

Excelente artigo para introdução de PDO, direto ao ponto!

[3] Comentário enviado por JhoniVieceli em 15/04/2008 - 13:33h

Isso ai Adilson vou add nos meus favoritos.

Boa pra caramba o artigo e de fácil entendimento

abraço!

[4] Comentário enviado por denis.roschel em 13/06/2008 - 09:05h

Parabéns pelo artigo! Muito didático

[5] Comentário enviado por admtempos em 01/06/2009 - 12:27h

Muito Bom este post principalmente para quem esta começando agora

[6] Comentário enviado por will fernando em 10/08/2009 - 15:00h

muito bom .. parabens !

[7] Comentário enviado por mbmaciel em 31/01/2010 - 16:48h

Artigo de alto nivel e muito bem escrito. Parabens!

[8] Comentário enviado por henbran em 26/05/2010 - 08:56h

Bom Dia.
ESTOU COM UMA DÚVIDA EM HERANÇA EXTENDS

tenho 1 classe:
___________________________________
class A{
public function funcaoA(){
//detalhes
}
}
ººººººººººººººººººººººººººººººººººººººººººººººººººººººººººººººººº

Então tenho outra classe:
___________________________________
class B extends A{
public function funcaoA(){
//detalhes
}
}
¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨
Quando tento instanciar a classe B, sendo estendida da classe A, não instancia.
ex. $instanciaB = new B(); // não funciona.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Se tiro o extends A da declaração da classe B (ficando assim: class B{ ... }), então instancia.
................................................................................................................
Já cheguei a testar todas as classes vazias, tentando saber se haveria algo de errado com as functions, porém mesmo assim continua no mesmo problema.
*******************************************************************************************
POR FAVOR, COMO EU DEVERIA FAZER ENTÃO???

[9] Comentário enviado por removido em 24/12/2010 - 15:46h

Muito bom. Parabéns!


Contribuir com comentário