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

PDO: PHP Data Object: Como fazer Conexão com Mysql usando PDO

Para 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.

1
2
3
4
5
6
$servidor_mysql = 'localhost';
$nome_banco = 'cartao';
$usuario = 'root';
$senha = '';
 
$conn = new PDO("mysql:host=$servidor_mysql;dbname=$nome_banco","$usuario","$senha");
$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.

PDO: PHP Data Object: Como Executar Comandos Sql

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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$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>";    
}
$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:

1
2
Pernambucana - Vanessa - 10
American Express - Eduardo - 10
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: PHP Data Object: Configurar tipo de Retorno

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:

1
2
3
4
5
6
7
8
9
10
11
12
13
$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>";
 
}
$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:

1
2
3
4
5
Array
(
    [0] => Pernambucana_Vanessa_10
    [1] => American Express_Eduardo_10
)
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$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>";
    }
}
$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á:

1
2
10
10
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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>";
}
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:

1
2
3
4
5
6
7
8
9
10
11
$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>";
}
$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 invocar 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”

PDO: PHP Data Object: Conclusão

PDO é uma classe excelente para trabalhar com banco de dados, o recurso de preparação do sql antes de sua execução, permite-nos montar sql segurados contra ataques de sql injection. A classe também permite você configurar vários tipos de retornos de uma dada consulta sql, o que facilita a vida dos webmasters. Além disso, a sintaxe, como você deve ter visto, é de fácil entendimento, ajudando muito quem está começando na jornada de progrador PHP.

Até o próximo artigo aqui no blog

PDO: PHP Data Object
4.8 (96%) 5 votes

Leave a Reply