PDO – PHP Data Object – Trocar de banco de dados já não é dor de cabeça
Se você desenvolve com PHP há algum tempo e necessitou trocar de banco de dados sabe que o PHP pode causar um certo problema, pois possui funções com nomes diferentes para conectar a banco de dados diferentes. O que muitas vezes inviabiliza o processo.
Aqueles que já trabalharam com Java sabem que existe algo chamado JDBC que resolve este problema, fornecendo uma camada de abstração de dados através de interfaces, bastando carregar o driver correto e utilizar sempre os mesmos métodos para acessar qualquer banco de dados.
Para os desavisados o PHP possui, desde a versão 5, algo parecido que se chama PDO – PHP Data Objects, permitindo o acesso a vários bancos de dados chamando sempre as mesmas funções.
Os drivers PDOs devem ser carregados pelo módulo PHP então temos que habilita-los e isso é feito dentro do arquivo php.ini
.
extension=pdo.so
extension=pdo_mysql.so
extension=pdo_pgsql.so
extension=pdo_sqlite.so
Normalmente não temos acesso ao arquivo php.ini
pois contratamos um serviço de hospedagem, então para ver os drivers que estão habilitados na hospedagem que contratamos devemos executar o código abaixo:
foreach(PDO::getAvailableDrivers() as $driver){
echo $driver.'<br />';
}
Como o próprio nome do recurso “PHP Data Objects” a conexão e a manipulação dos dados é feita utilizando uma classe do PHP chamada PDO – que deve ser instanciado com as informações de conexão ao banco.
Exemplo:
$conn = new PDO('mysql:host=localhost;port=3306;dbname=teste', 'root', '123456');
Como podemos notar o construtor do objeto PDO aceita três parâmetros, o primeiro é uma string contendo o driver a ser utilizado mysql
, o local onde o banco esta rodando localhost
, a porta que o banco esta escutando 3306
e o nome do banco de dados teste
. O segundo parâmetro é o usuário de acesso ao banco de dados e o terceiro é a senha de acesso.
A partir de agora podemos utilizar o objeto armazenado em $conn
para manipular os dados no banco de dados.
Como sabemos quando estamos trabalhando com banco de dados vários erros podem acontecer como o banco de dados estar indisponível entre outra coisas. O PDO pode ser configurado para gerar exceção quando algum erro destes ocorrem sendo capturados com um bloco try{...}catch(){...}
sendo lançada a exceção PDOException
.
Abaixo um exemplo de inserção utilizando a classe PDO:
try{
//instancia o objeto PDO, conectando com o banco mysql
$conn = new PDO('mysql:host=localhost;port=3306;dbname=teste', 'root', '123456');
//configurando para utilizar exceções
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//executa as instruções SQL
$conn->exec("INSERT INTO usuarios (login,senha,nome) VALUES ('rodrigo', '123456', 'rodrigo')");
$conn->exec("INSERT INTO usuarios (login,senha,nome) VALUES ('thiago', '654321', 'Thiago')");
$conn->exec("INSERT INTO usuarios (login,senha,nome) VALUES ('maria', '654123', 'Maria')");
//fecha a conexão
$conn = null;
}catch (PDOException $i){
//se houver exceção, exibe
print "Erro: <code>" . $i->getMessage() . "</code>";
}
?>
Como vemos nas linha 11,12,13 utilizamos o método exec
para executar comando SQL no banco de dados.
Agora veremos como consultar utilizando a classe PDO:
try{
//instancia o objeto PDO, conectando com o banco mysql
$conn = new PDO('mysql:host=localhost;port=3306;dbname=teste', 'root', '123456');
//configurando para utilizar exceções
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//executa a instrução de consulta
$result = $conn->query("SELECT senha,login FROM usuarios");
if($result){
//percorre os resultados via o laço foreach
foreach($result as $linha){
//exibe o resultado
print $linha['login'] . " - " . $linha['senha'] . "<br>\n";
}
}
//fecha a conexão
$conn = null;
}catch (PDOException $i){
//se houver exceção, exibe
print "Erro: <code>" . $i->getMessage() . "</code>";
}
Como vimos para executar uma consulta utilizanos a função query
que retorna um objeto de resposta PDOStatement
que pode ser percorrido utilizando um laço foreach
(linha 11).
Também é possível percorrer um objeto PDOStatement
utilizando o método fetch
dele tratar cada linha da consulta como um objeto.
Exemplo:
try{
//instancia o objeto PDO, conectando com o banco mysql
$conn = new PDO('mysql:host=localhost;port=3306;dbname=teste', 'root', '123456');
//configurando para utilizar exceções
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//executa a instrução de consulta
$result = $conn->query("SELECT login, senha FROM usuarios");
if($result){
//percorre os resultados via o fetch()
while ($linha = $result->fetch(PDO::FETCH_OBJ)){
//exibe resultado
print $linha->login . " - " . $linha->senha . "<br>\n";
}
}
//fecha a conexão
$conn = null;
}catch (PDOException $i){
//se houver exceção, exibe
print "Erro: <code>" . $i->getMessage() . "</code>";
}
?>
Na linha 13 chamamos o método fetch
que recebe a constante PDO::FETCH_OBJ
que é responsável por definir que o retorno será um objeto. Também podemos passar as constantes PDO::FETCH_ASSOC
que retorna um array com os índices sendo os nomes das colunas da consulta e PDO::FETCH_NUM
que retorna um array com os índices numéricos.
Outra funcionalidade interessante que ameniza muitos erros é os famosos do prepared statements. Veja o exemplo abaixo:
<?php
try{
//instancia o objeto PDO, conectando com o banco mysql
$conn = new PDO('mysql:host=localhost;port=3306;dbname=teste', 'root', '');
//configurando para utilizar exceções
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//prepara a consulta
$result = $conn->prepare("INSERT INTO usuarios (login,senha,nome) VALUES (?, ?, ?)") ;
//insere os valores nas ?
$valores = array('rodrigo', '123456', 'rodrigo');
//executa o comando SQL
$result->execute($valores);
//fecha a conexão
$conn = null;
}catch (PDOException $i){
//se houver exceção, exibe
print "Erro: <code>" . $i->getMessage() . "</code>";
}
?>
Com o uso dos prepared statements não precisamos ficar nos preocupando em concatenar várias variáveis, ou nos preocuparmos com escape de aspas e tudo mais, basta colocar os valores no array que será passado por parâmetro para o método execute
.
Espero que tenham gostado. Para mais informações consulte a documentação da classe PDO