PDO (PHP Data Object)
PDO (PHP Data Object)
A partir da versão 5 do PHP, PDO foi adicionado ao núcleo do sistema. PDO é uma classe para trabalhar com banco de dados no PHP de forma orientada a objetos. Dentre os principais benefícios em utilizar PDO podemos citar:
- PDO vem compilado no núcleo do PHP e portanto é bem mais rápido do que uma classe para trabalhar com banco de dados comum
- PDO possui uma camada de abstração para trabalhar com banco de dados distintos, o que te permite executar comandos e trabalhar com o retorno dos dados do banco de forma semelhante para qualquer banco de dados suportado.
- PDO já possui controle de segurança para evitar ataques do tipo Sql Injection.
- Como trata-se de uma classe, você pode criar suas próprias classes abarcando todo o recurso que PDO já possui graças a herança que a programação OO nos oferece. Por exemplo, lembram-se da classe PDOPaginator que criei para trabalhar com paginação? Quem não leu o artigo, veja-o no link: Paginação no PHP com PDO
Como fazer a conexão com o mysql usando PDO
Para se conectar com o banco de dados, quando você instancia a classe PDO em um dado objeto, você deve passar os parâmetros necessários. Veja o exemplo abaixo. Comento depois.
$servidor_mysql = 'localhost';
$nome_banco = 'cartao';
$usuario = 'root';
$senha = '';
$conn = new PDO("mysql:host=$servidor_mysql;dbname=$nome_banco","$usuario","$senha");
1- O primeiro parâmetro é uma string de conexão com informações sobre: o driver a ser utilizado, no nosso caso foi o mysql, o url do servidor do banco de dados e o nome do banco de dados que você quer conectar-se.
2- O segundo parâmetro é o nome do usuário do banco de dados
3- O terceiro parâmetro é a senha do usuário do banco de dados.
Como pode ser visto acima, para facilitar, eu utilizei variáveis, assim sendo, bastará a você alterar os valores corretos nas variáveis: $servidor_mysql, $nome_banco, $usuario, $senha, que a instanciação da classe PDO no objeto $conn será efetuada de forma correta. Contudo, note que estou subentendendo que você irá trabalhar com banco de dados Mysql.
Agora que você já viu como se conectar ao banco de dados com PDO, como fazer consultas simples nas tabelas e como executar comandos de inclusão e exclusão de dados bem como atualização? Bem, fique tranquilo que veremos a seguir como isso é feito.
A forma mais simples de executar um comando ou consulta é utilizar o método query do PDO. Para ilustrar vou tomar como princípio que tenhamos uma tabela chamada cartao e que ela possua três colunas: nm_cartao (nome do cartão), nm_titular (nome do titular do cartão), dia_vencimento (dia de vencimento do cartão). Veja os exemplos abaixo:
$servidor_mysql = 'localhost';
$nome_banco = 'cartao';
$usuario = 'root';
$senha = '';
$conn = new PDO("mysql:host=$servidor_mysql;dbname=$nome_banco","$usuario","$senha");
//Insere três registros na tabela cartao
$conn->query("insert into cartao values ('Marisa','Vanessa',10)");
$conn->query("insert into cartao values ('Hering','Diogo',12)");
$conn->query("insert into cartao values ('American Express','Eduardo',10)");
//Atualiza a tabela cartao, alterando o nome do cartao do titular Vanessa
$conn->query("update cartao set nm_cartao='Pernambucana' where nm_titular='Vanessa'");
//Exclui um registro da tabela cartao
$conn->query("delete from cartao where nm_titular='Diogo'");
//Seleciona todos os registros da tabela cartao e imprime na tela
$tb= $conn->query("select * from cartao");
while($l = $tb->fetch(PDO::FETCH_ASSOC)){
echo $l["nm_cartao"] . " - " . $l["nm_titular"] . " - " . $l["dia_vencimento"] . "<br>";
}
O script acima vai imprimir na tela o seguinte:
Pernambucana - Vanessa - 10 American Express - Eduardo - 10
O método fetch permite você escolher o formato que os dados irão retornar, no nosso caso foi passado como parâmetro PDO::FETCH_ASSOC, o que retorna um array com o nome das colunas como índice. Outras opções são:
PDO::FETCH_NAMED – praticamente igual ao FETCH_ASSOC, com a diferença de que caso existam colunas com mesmo nome no retorno da consulta SQL, FETCH_NAMED irá juntar os valores das duas ou mais colunas num único array.
PDO::FETCH_FUNC – Permite você passar uma função que irá interagir com os valores das colunas. Note que os valores das colunas serão passados a função como parâmetros. Veja o exemplos abaixo:
$tb= $conn->prepare("select * from cartao");
$tb->execute();
function add_slug($a, $b, $c){
return $a . "_" . $b . "_" . $c;
}
while($l = $tb->fetchAll(PDO::FETCH_FUNC, 'add_slug')){
echo "<pre>";
print_r($l);
echo "</pre>";
}
O código acima irá imprimir o seguinte:
Array
(
[0] => Pernambucana_Vanessa_10
[1] => American Express_Eduardo_10
)
PDO::FETCH_BOTH – Irá retornar um array indexado tanto pelo nome da coluna quanto pelo índice numérico a iniciar por 0.
PDO::FETCH_GROUP – Agrupa valores iguais da primeira coluna, no nosso caso, usuários com o mesmo cartão serão agrupados pelo índice do nome do cartão.
PDO::FETCH_KEY_PAIR – Exige que o retorno do sql possua exatamente duas colunas, agrupando os valores da primeira coluna como índice e os valores da segunda como valores do array de retorno.
PDO::FETCH_UNIQUE – retorna somente valores únicos, caso houvesse duas pessoas com o mesmo cartão, FETCH_UNIQUE retornaria apenas uma.
PDO::FETCH_BOUND – Util quando você trabalha com o método bindColumn(), atribui o valor da coluna à variável informada neste método.
PDO::FETCH_CLASS – Retorna uma nova instância da classe que você passa como parâmetro. Caso a classe passada como parâmetro tenha propriedades com os mesmos nomes das colunas, os valores serão atualizados, caso negativo, uma nova propriedade com o nome da coluna será criada no objeto instanciado. É como um objeto filho que herda as propriedades do pai e tem também suas próprias propriedades.
Veja o código abaixo para entender melhor:
$tb= $conn->query("select * from cartao");
class Cartao{
public $nm_cartao;
public $nm_titular;
public function pega_valor($x){
return $this->$x;
}
}
while($l = $tb->fetchAll(PDO::FETCH_CLASS,"Cartao")){
foreach($l as $titular){
echo $titular->pega_valor("dia_vencimento") . "<br>";
}
}
A saída do código acima será:
10 10
Embora a classe instanciada “Cartao” não possui uma propriedade “dia_vencimento”, essa propriedade existe pois é uma coluna da tabela que foi convertida em uma propriedade do objeto instanciado.
PDO::FETCH_CLASSTYPE – Utilizado junto com FETCH_CLASS, define que é para usar o nome da primeira coluna como nome da classe de retorno.
PDO::FETCH_INTO – Praticamente igual a PDO::FETCH_CLASS, com a diferença de que você passa um objeto já instanciado, o qual terá suas propriedades atualizadas. Um detalhe sobre o PDO::FETCH_INTO é que não funciona com o método fechAll, ou seja, você terá que invocar o método setFetchMode. Veja como ficaria o código PHP:
class Cartao{
public $nm_cartao;
public $nm_titular;
public function pega_valor($x){
return $this->$x;
}
}
$cartao = new Cartao();
$tb= $conn->prepare("select * from cartao");
$tb->setFetchMode(PDO::FETCH_INTO,$cartao);
$tb->execute();
foreach($tb as $titular){
echo $titular->pega_valor("dia_vencimento") . "<br>";
}
PDO::FETCH_SERIALIZE – Igual FETCH_INTO porém o objeto é providenciado como uma string serializada.
PDO::FETCH_NUM – retorna um array indexado pelo número da coluna, iniciando com o número 0. Ideal para quem quer obter o retorno de uma consulta sql no formato de array.
PDO::FETCH_OBJ – retorna um objeto anônimo onde as colunas das tabelas se tornam propriedades dos objetos.
PDO::FETCH_LAZY – combina PDO::FETCH_BOTH com PDO::FETCH_OBJ
Caso você vá pegar dados oriundos de um formulário web ou mesmo de um banco de dados para formar a consulta sql ou comando sql, o ideal é utilizar o método do PDO prepare e bindParam. Utilizando esses métodos: prepare e bindParam, você assegura que seu script estará livre de “sql injection”. Veja abaixo como trabalhar com o prepare e bindParam:
$nome = 'Eduardo';
$dia = 10;
$tb= $conn->prepare("select * from cartao where nm_titular = :nm and dia_vencimento = :dia");
$tb->bindParam(":nm", $nome, PDO::PARAM_STR);
$tb->bindParam(":dia", $dia, PDO::PARAM_INT);
$tb->execute();
while($l = $tb->fetch(PDO::FETCH_ASSOC)){
echo $l['nm_cartao'] . "\t" . $l["nm_titular"] . "\t" . $l["dia_vencimento"] . "<br>";
}
Na formação do sql, quando usando o prepare, você define um nome que será substituído por outro valor colocando dois pontos antes deste nome. Após isso, quando invocando o método bindParam, você deve informar o mesmo nome que adicionou na formação do sql como primeiro parâmetro do método. O segundo parâmetro de bindParam é a variável que possui o valor que deve ser substituído. Por fim, o terceiro parâmetro é uma constante do PDO que informa ao sistema que tipo de dado você está adicionando ao sql. Os valores possíveis são:
- PDO::PARAM_STR – para valores strings, datas, horas…
- PDO::PARAM_INT – para valores inteiros
- PDO::PARAM_BOOL – para valor booleano (true ou false)
- PDO::PARAM_NULL – valor nulo (null)
- PDO::PARAM_LOB – representa valores de grande quantidade de dados
- PDO::PARAM_STMT – representa um conjunto de registros, atualmente não é suportado por nenhum driver
- PDO::PARAM_INPUT_OUTPUT – especifica que é um parâmetro de entrada e saída para “stored procedures”
Bom, vou ficando por aqui. Até o próximo artigo aqui no Livro PHP




















O método “query” é utilizado para consultas que retornam resultados tabulares (como o SELECT) e devolve um objeto da
classe PDOStatement com o resultado. Já o método “exec” é utilizado para consultas que não retornam resultados
tabulares (como o INSERT, UPDATE, DELETE) e retorna apenas o número de linhas afetadas.
Olá Anderson tudo bem contigo? Esse trecho acima eu copiei de um site, o conteudo acima confere? Pois percebi que vc usa o metodo query em tudo, me dê uma luz pois quero começar com o pdo da maneira correta, um abração e muito obrigado pela atenção.
16 / 03Rozael, não está errado, mas nada te impede de usar o query para executar comandos insert, update e delete. O mesmo é válido para o prepare e execute. Veja o exemplo abaixo:
$tb = $conn->query(“update categorias set nm_categoria=’Matemática’ where nm_categoria=’Matemática’”);
ou
$tb = $conn->prepare(“update categorias set nm_categoria=’Matemática’ where nm_categoria=’Matemática’”);
$tb->execute();
Resumindo, o exec é limitado para apenas executar comandos sem retorno de registros do banco, já o query executa comandos e também retorna registros do banco. Além deles tem o prepare que é usado junto com o execute(). Uso com mais frequência o prepare mesmo, pois geralmente passo valores oriundos de formulários web para montar o query. Por exemplo, como você montaria o query para selecionar dados de um registro com o nome selecionado pelo usuário? O correto é usar o prepare / bindParam / execute para evitar sql injection. Veja:
$nm = “Matemática”;
$tb = $conn->prepare(“select * from categorias where nm_categoria=:nm”);
$tb->bindParam(“:nm”, $nm, PDO::PARAM_STR);
$tb->execute();
while($l= $tb->fetch(PDO::FETCH_ASSOC)){
28 / 03echo $l["nm_categoria"] . “<br>”;
}