PDO é um módulo do PHP, montado com foco na Orientação a Objetos, e cujo objetivo central é estabelecer uma padronização da forma como PHP se comunica com os diferentes sistemas gerenciadores de bancos de dados relacionais. Muitas fontes refirem-se a PDO como uma camada de abstração de SQL, e diz-se que é possível escrever o código apenas uma vez e usá-lo depois indefinidamente, para qualquer SGBD. Na realidade, não é bem assim, pois as sintaxes da linguagem SQL são levemente diferentes de um SGBD para outro, e iguais apenas entre alguns deles. De qualquer forma, é a maneira mais próxima de uma unificação que temos para o acesso ao BD em PHP.
De qualquer forma, a lógica por trás do uso de PDO é bastante simples: PDO é uma classe, com atributos e funções. Se você sabe algo sobre Orientação a Objetos, já deve saber que um Objeto é a instância de uma classe. Assim, se eu tenho a classe PESSOA, com os atributos NOME e IDADE, e eu crio o objeto P1, eu devo informar valores para os atributos de P1. Digamos que sejam esses: Nome="Juca" e Idade="18".
Além dos atributos, temos as funções, ou métodos, que são "coisas que um objeto de tal classe faz". Para executar um método, usamos o sinal "->", então, no exemplo que eu estava dando, digamos que eu execute um método chamado "aniversário": "P1->aniversario", e este método incremente o valor de "Idade". Quando eu exibir o valor de P1.idade, será agora 19.
Depois desta rápida rememoração do trabalho com Orientação a Objetos, vamos falar de PDO.
SIMPLICIDADE E RAPIDEZ
Usando PDO, temos um acesso super simplificado à base de dados. A primeira coisa que podemos notar é que, no comando em que passamos as especificações do banco de dados e os dados de acesso a ele, a sintaxe é sempre a mesma para TODOS os gerenciadores de banco de dados suportados.
Mas aí, vem a primeira pergunta: como podemos descobrir quais são os sistemas gerenciadores de banco de dados que nossa instalação do PHP no servidor Apache está suportando? Vamos ao nosso primeiro código de hoje:
foreach(PDO::getAvailableDrivers() as $driver){
echo $driver."
";
}
O resultado vai ser uma coisa mais ou menos assim:
dblib
firebird
mysql
odbc
pgsql
sqlite
sqlite2
A primeira pergunta que vem à mente de vocês, com certeza, é: por quê eu vou querer conectar meu programa ao BD usando PDO? E a resposta é muito simples: por uma série de motivos. Vamos a eles.
Usando funções como "mysql_connect", temos um conjunto de parâmetros requeridos em uma certa ordem e de uma certa maneira, que podem ou não serem diferentes dos comandos utilizados em funções criadas para suporte a SGBD diferentes. Com isso, para cada um destes sistemas (Oracle, SQLServer, SQLite...) temos que reaprender como trabalhar, nem que sejam apenas detalhes das linhas de comando.
Usando PDO, temos que primeiro criar um objeto de acesso à base de dados, mas que a partir de sua criação, poderá ser trabalhado sempre com os mesmos comandos, independente do sistema de banco de dados utilizado, o que é uma grande vantagem especialmente quando surge a necessidade de migrar para outro destes sistemas, pois só a linha de criação do objeto é modificada. E mesmo assim, não muito.
Outro detalhe é que as funcionalidades do uso de PHP Data Objects estão na verdade contidas em um programa compilado em C, que faz parte do "coração" do interpretador PHP que funciona nos servidores (como o Apache). Isso é muito importante porque seu processamento é muito mais veloz do que aquele de funções armazenadas em bibliotecas, e que precisam ser, portanto, interpretadas antes de executadas (como mysql_connect, por exemplo).
Ainda outra vantagem é que usando a forma mais resumida e simples possível de consulta ao banco de dados prevista pelas especificações de PDO, podemos "pular" a fase de carregamento do resultado da consulta para uma variável (normalmente, usando por exemplo as classes criadas para acesso às bases de dados MySQL, deve-se abrir o acesso ao banco, depois carregar a consulta, com todos os seus resultados, em uma variável, e depois percorrê-la usando o Fetch. Usando PDO é possível passar diretamente a esta última fase).
Veremos como fazer tudo isso logo em seguida. Mas há um motivo para vocês aprenderem a usar PDO e passarem a amar eles. Primeiro, o motivo banal de que Data Objects são elementos-chave da programação orientada a objetos. Segundo, por um motivo mais óbvio: se PHP4 não suportava PDO, e PHP5 dá suporte total, é sabido e comentado mundialmente que a sexta versão da linguagem, PHP6, NÃO VAI SUPORTAR AS ANTIGAS FUNÇÕES DE ACESSO E MANIPULAÇÃO DE BANCOS DE DADOS, sobrando apenas os PHP Data Objects. E quem não se adaptar, possivelmente estará fora da jogada.
Claro que sempre é possível manter o servidor da sua empresa usando uma versão velha do PHP, que suporte as velhas funções das bibliotecas. Mas aí você não vai ter, também, as vantagens da nova versão da linguagem.
CRIANDO O OBJETO
A primeira coisa a se criar é o objeto, a camada de abstração do acesso ao banco de dados.
$banco = new PDO("mysql:host=hostdobancodedados:3306;dbname=basededados", "usuario", "senha");
O comando acima é simples de entender. $banco será meu objeto, instanciando a classe PDO, com os seguintes parâmetros: a base de dados é MySQL, eu passei o endereço do host, e uma porta (3306). A porta na verdade é opcional, e podemos NÃO ESCREVER o dois-pontos e o número da porta, e aí, o sistema encontra um caminho sozinho. Só vou escrever algo ali se eu quiser forçar o acesso por uma porta específica, digamos, uma porta que eu tenha deixado aberta na minha Firewall. Depois, temos "dbname", que é o nome da base de dados, o nome de usuário, e a senha.
Notem que há uma divisão destes parâmetros. Os três primeiros estão dentro das primeiras aspas simples. Estes partâmetros (e muitos outros mais possíveis) são informações sobre o banco de dados, onde ele está e como será aberto. O próximo conjunto de aspas circunda o nome de usuário, e o último, a senha.
Eu acabo de criar um objeto $banco, que instancia uma classe chamada PDO. Notem que na minha linha de comando acima, há a menção a "mysql", mas de acordo com a lista de SGBD que apareceu diante do primeiro código que escrevemos, eu poderia ter escrito ali "sqlite", ou "firebird", ou qualquer outra das opções suportadas.
A partir deste comando, NÃO IMPORTA QUAL sistema gerenciador de banco de dados eu esteja usando, OS COMANDOS SERÃO SEMPRE IGUAIS, e aqui reside a mágica, a vantagem, de se trabalhar com PDO. Eu posso criar este objeto $banco numa linha qualquer no começo do código, e quando eu quiser trocar o SGBD do meu servidor, basta mudar aquela linha, que o resto do programa continua igual.
Digamos que eu tenha uma tabela, neste banco de dados, chamada "noticias", e que eu queira exibir na tela o título e o texto de cada uma das matérias armazenadas.
foreach ($banco->query("select titulo, texto from noticias") as $dados) {
Percebam que, ao invés de fazer a consulta ao BD e armazená-la numa variável (uma matriz), para depois percorrê-la exibindo os resultados, eu fui diretamente para o FOREACH, executando, a cada "volta" do laço de repetição, a consulta a uma linha da tabela de dados, ou melhor, da consulta que eu defini na query SQL lançada entre aspas simples. E descarrego esta linha, sob a forma de um array, em $dados.
O resto dos comandos dentro do laço de repetição são bastante familiares para quem tem um mínimo de compreensão das linguagens PHP e HTML: eu estou exibindo os resultados na tela, de forma simplificada, com os títulos em negrito e os textos em fonte normal.
NOTA IMPORTANTE: quando usamos FOREACH, o array, que neste meu exemplo, contém os dados na mesma ordem que designamos no SELECT. Ou seja, neste exemplo, $dados[0] é o título, $dados[1] é o texto.
INSERT, UPDATE, DELETE
Já vimos como executar consultas, e vimos que há uma grande vantagem em termos de economia de memória porque não precisamos carregar uma variável com a matriz contendo todo o resultado da consulta. Bom. Agora, veremos uma função da classe PDO que nos permite executar querys SQL. Esta função tem o nome de "exec", o que torna seu propósito de existir bastante óbvio. Ela retorna um valor inteiro, que é o número de registros afetados pela query. A sintaxe é a mais simples possível:
$resultado = $banco->exec("insert into cadenqopcao values (0, 12, ´Teste´, ´Teste PDO´);");
Depois, podemos testar se o número de resultado é zero (quando não executou nada) ou algo diferente.
Este post está em construção e voltarei para aumentá-lo assim que der tempo.