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.582 ]

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

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

Aumente sua produção em PHP

Leitura recomendada

Paginando resultados com a classe Generic Easy Pagination

Provendo dados em um servidor PostgreSQL através do Apache e PHP

Abordagem exemplificada à Orientação a Objetos com PHP

Executando comandos DML em base de dados MySQL através do Eclipse PHP (Bônus: Temas e Fontes no Eclipse)

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




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner
Linux banner
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts