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