Como acessar o banco de dados com PHP7: mysqli ou PDO?

(Última atualização em: 30 de maio de 2017)

Com a nova atualização do php de 5.6 para a versão 7, a extensão mysql_* para conexão com banco de dados, já depreciada na versão antiga, deixou de existir! Já se recomendava utilizar as extensões mysqli ou PDO (PHP Data Objects) e agora as duas se tornaram nossas únicas opções para essa funcionalidade.

Mas, qual das duas utilizar? As duas fazem a mesma coisa?
É comum que este tipo de duvida apareça, até mesmo para quem já conhecia as extensões anteriormente!

Quando estamos desenvolvendo um sistema em PHP, uma hora ou outra nos deparamos com a necessidade de utilizar um banco de dados. Nesse momento podemos escolher qualquer um: PostgreSQL, MySQL, Oracle, SQLite, entre outros.

O mais comum entre a maioria dos desenvolvedores é o MySQL. Assim, podemos usar a extensão mysqli do php para realizar a conexão! Então, ao desenvolver uma query com a extensão mysqli temos algo como:

<?php
  $mysqli = new mysqli("localhost", "usuario", "senha", "database");

  public function buscaPorNome(String $nome){ 
    $query = "SELECT * FROM Pessoa WHERE NOME = ? ";

    $statement = $mysqli->prepare($query);
    $statement->bind_param("s",$nome)
    $statement->execute();

    $result = $statement->get_result();
    $pessoaArray = $result->fetch_assoc();

    return $pessoaArray;
  }
?>

Perfeito, realizamos uma busca simples com um parâmetro através da extensão mysqli. Mas, e com PDO? nesse caso ficaria:

<?php
  $pdo = new PDO('mysql:host=localhost;dbname=database', 'usuario', 'senha');

  public function buscaPorNome(String $nome){
    $query = "SELECT * FROM Pessoa WHERE NOME=:nome";

    $statement = $pdo->prepare($query);
    $statement->bindValue(":nome",$nome);
    $statement->execute();

    $pessoaArray = $stm->fetch(\PDO::FETCH_ASSOC);

    return $pessoaArray;
  }
?>

Ótimo, as duas formas funcionam e retornam o mesmo array $pessoaArray! Mas, já da pra ver que existem algumas diferenças entre as extensões.

Primeiro que ao instanciar PDO, precisamos de um prefixo mysql antes de passar o host, entretanto, com mysqli, não havia essa necessidade. Isso porque o PDO, ao contrario do Mysqli, consegue trabalhar com vários bancos de dados, então precisamos dizer com qual banco vamos trabalhar.

Caso houvesse uma migração de MySql para PostgreSQL, a única mudança necessária no nosso projeto com PDO seria:

$pdo = new PDO('pgsql:host=localhost;dbname=database', 'usuario', 'senha');

Com mysqli essa migração simples não seria possível!

Outra diferença nos códigos é que com mysqli passamos o atributo $nome do método associado ao atributo ? da query pelo método ->bind_param . Já com PDO definimos um atributo :nome dentro da query e depois relacionamos :nome com $nome pelo método ->bindValue.

Além disso, com mysqli, precisamos especificar o tipo do atributo $nome como String através da letra “s”. Isso porque o método ->bind_param segue a estrutura:

->bind_param("primeira silaba do tipo do parametro",$parametro)

Já o método ->bindValue segue a seguinte estrutura:

->bindValue(":parametroDaQuery",$parametroQueSeraAtribuido)

Isso faz com que a realização de queries em PDO seja muito mais fácil pois sabemos exatamente qual atributo estamos associando. No caso de termos mais de um parametro o código com mysqli ficaria:

public function buscaPorNome(String $nome, Long $id){
  $query = "SELECT * FROM Pessoa WHERE NOME = ? AND ID = ?";

  $statement = $mysqli->prepare($query);
  $statement->bind_param("si",$nome,$id);
  $statement->execute();

  $result = $statement->get_result();
  $arrayPessoa = $result->fetch_assoc();

  return $arrayPessoa;
}

Agora precisamos seguir a ordem com que os parametros ? foram inseridos na query e especificar o tipo do $id como Int através da letra i. Caso houvesse uma simples mudança na ordem:

$query = "SELECT * FROM Pessoa WHERE ID = ? AND NOME = ?";

precisariamos lembrar de inverter os parametros e as especificações de tipo no método bind_param() para:

$statement->bind_param("is",$id,$nome);

Já com PDO, a mesma situação ficaria:

public function buscaPorNome(String $nome, Int $id){
  $query = "SELECT * FROM Pessoa WHERE ID = :id AND NOME = :nome";

  $statement = $pdo->prepare($query);
  $statement->bindValue(":nome",$nome);
  $statement->bindValue(":id",$id);

  $statement->execute();
  $pessoaArray = $stm->fetch(\PDO::FETCH_ASSOC);

  return $pessoaArray;
}

Assim, não importa a ordem dos parâmetros, sempre estamos associando o parâmetro certo!

Com nosso exemplo simples de buscar uma pessoa pelo nome no banco de dados podemos perceber algumas vantagens do PDO e outras do mysqli:

  • Com PDO conseguimos utilizar varios bancos de dados, facilitando possiveis migrações além de nos possibilitar desenvolver códigos mais semanticos, o que facilita muito a manutenção e melhora a legibilidade
  • Com mysqli trabalhamos especificamente com banco de dados MySQL, o que da para essa extensão maior perfomance e algumas funcionalidades a mais

Então, quando devemos utilizar PDO ou mysqli? Para um projeto em que performance é de extrema importância, podemos optar pelo mysqli. Em outro projeto, no qual vamos trabalhar com mais de um banco de dados, podemos optar pelo PDO! Por isso, é importante refletir sobre qual deles utilizar em nossos projetos a partir de nossas necessidades e limitações.

Nesse post a gente viu as principais diferenças entre a extensão mysqli e PDO, um pouco da sintaxe dos dois e como escolher qual deles utilizar em nossos projetos! Mas, e você? Qual você mais utiliza, ou pretende utilizar, no seu dia-a-dia? Comente aqui!

Quer ver mais diferenças entre PDO, mysqli e o antigo mysql_*? Da uma olhada aqui no php.net (Disponível em inglês). Você também pode encontrar tudo sobre PHP e mysqli nos cursos online da alura: PHP e MySQL I e PHP e MySQL II

  • Golpian

    Eu fiz uns testes aqui com PDO e funções de segurança e gostei, da pra combater legal as sqlinjections já o msqli tem estas funçoes?

    • André Chaves

      Olá Golpian, tanto PDO quanto mysqli possuem formas de lidar com SQL Injection com queries preparadas (prepared queries)! Você pode verificar a sintaxe nos exemplos desse post 🙂

      Obrigado por compartilhar sua duvida com a gente!

  • Anderson Filipe

    Muito bom o post!

    • André Chaves

      Muito obrigado, Anderson! =)

  • Pingback: Blog da Alura – Evitando SQL Injection com PHP()

  • Eduardo Garbin

    Otimo tema! Não sabia a diferença entre os usos. Se soubesse antes, certamente PDO seria usado em um projeto.

    Parabens

Próximo ArtigojQuery 3.0 Final é lançado