mysqli ou DOP - quais são os prós e os contras? [fechadas]


342

Em nosso lugar, estamos divididos entre usar o mysqli e o PDO para coisas como instruções preparadas e suporte a transações. Alguns projetos usam um, outros o outro. Há pouca probabilidade realista de mudarmos para outro RDBMS.

Prefiro a DOP pelo único motivo de permitir parâmetros nomeados para instruções preparadas e, tanto quanto sei, o mysqli não.

Existem outros prós e contras na escolha de um sobre o outro como padrão à medida que consolidamos nossos projetos para usar apenas uma abordagem?


5
Este artigo ajudará a escolher qual deles usar. Se você considerar o desempenho, isso pode ajudá-lo a escolher.
ravi404

3
É engraçado quantas pessoas votaram e estrelaram uma pergunta que "não é construtiva". O problema é que o tópico completo é muito construtivo - talvez os moderadores devam levar isso em consideração ao julgar se uma pergunta é construtiva ou não?
marlar 27/06/13

@ marlar Eu muuuitoooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo Este é realmente o maior problema no StackOverflow. Excelentes perguntas / discussões estão sempre fechadas.
Sliq

Respostas:


243

Bem, você poderia argumentar com o aspecto orientado a objetos, as declarações preparadas, o fato de se tornar um padrão etc. Mas eu sei que, na maioria das vezes, convencer alguém a trabalhar melhor com um recurso matador. Então aqui está:

Uma coisa muito boa com o DOP é que você pode buscar os dados, injetando-os automaticamente em um objeto. Se você não deseja usar um ORM (porque é apenas um script rápido), mas gosta de mapear objetos, é MUITO legal:

class Student {

    public $id;
    public $first_name;
    public $last_name

    public function getFullName() {
        return $this->first_name.' '.$this->last_name
    }
}

try 
{
    $dbh = new PDO("mysql:host=$hostname;dbname=school", $username, $password)

    $stmt = $dbh->query("SELECT * FROM students");

    /* MAGIC HAPPENS HERE */

    $stmt->setFetchMode(PDO::FETCH_INTO, new Student);


    foreach($stmt as $student)
    {
        echo $student->getFullName().'<br />';
    } 

    $dbh = null;
}
catch(PDOException $e)
{
    echo $e->getMessage();
}

12
existe uma diferença entre o acima e $mysqliResult->fetch_object("student");?
Andy Fleming

2
@ e-satis não, eu uso PHP. Os campos públicos violam o encapsulamento, por AS A BEST PRACTICEisso é apenas ... lol :) O Google não usa campos públicos, apenas acessadores: google-styleguide.googlecode.com/svn/trunk/… .
OZ_

6
@ e-satis: Desculpe por entrar, mas getters e setters são necessários se você deseja controlar o que acontece quando as variáveis ​​são alteradas. Caso contrário, você simplesmente não poderá garantir o estado interno do seu objeto (isso é especialmente um problema se você tiver outro objeto dentro). Isso é totalmente independente da linguagem. @OZ_: Facilite-se. Críticas pessoais só colocarão alguém na defensiva.
James P.

2
@monadic: Concordo. O encapsulamento é obviamente um argumento válido ao lidar com componentes principais, objetos complexos etc., no entanto, como representações de registros que, de outra forma, seriam associados de leitura e gravação. matrizes, isso é aceitável. Além disso, permite uma verificação mais fácil do tipo, à medida que os registros flutuam pelo sistema.
Dan Lugg

15
Espero que não seja minoria aqui, mas não acho que as respostas devam ser julgadas sobre sua segurança em relação a novos desenvolvedores. Parece duro, mas é verdade. O objetivo de uma resposta no SO não é apenas fornecer código de copiar e colar, mas também fornecer entendimento. Não é tarefa do respondente garantir que todas as falhas de segurança ou falhas de padrão sejam abordadas em um exemplo, porque, convenhamos, o aplicativo no qual o código é copiado é inerentemente diferente do que qualquer outro aplicativo usando o mesmo código.
Mattygabe

57

Mover um aplicativo de um banco de dados para outro não é muito comum, mas, mais cedo ou mais tarde, você poderá trabalhar em outro projeto usando um RDBMS diferente. Se você estiver em casa com a DOP, haverá pelo menos uma coisa a aprender nesse momento.

Além disso, acho a API do PDO um pouco mais intuitiva e parece mais verdadeiramente orientada a objetos. O mysqli parece que é apenas uma API processual que foi objetivada, se você entende o que quero dizer. Em suma, acho mais fácil trabalhar com a DOP, mas isso é subjetivo.


25

Comecei a usar o DOP porque o suporte à declaração é melhor, na minha opinião. Estou usando uma camada de acesso a dados no estilo ActiveRecord e é muito mais fácil implementar instruções geradas dinamicamente. A ligação de parâmetro do MySQLi deve ser feita em uma única chamada de função / método, portanto, se você não souber até o tempo de execução quantos parâmetros deseja vincular, será forçado a usar call_user_func_array()(acredito que esse seja o nome da função correto) para selects . E esqueça a ligação simples de resultados dinâmicos.

Acima de tudo, gosto da DOP porque é um nível de abstração bastante razoável. É fácil usá-lo em sistemas completamente abstratos, nos quais você não deseja escrever SQL, mas também facilita o uso de um sistema de tipo puro de consulta mais otimizado, ou a combinação dos dois.


2
A associação de resultados com consultas geradas dinâmicas é possível, nós fazemos isso em nossos aplicativos. No entanto, é uma dor enorme.
Pim Jager

17

O DOP é o padrão, é o que a maioria dos desenvolvedores espera usar. O mysqli era essencialmente uma solução sob medida para um problema específico, mas possui todos os problemas de outras bibliotecas específicas do DBMS. A DOP é onde todo o trabalho duro e pensamento inteligente irão.


15

Aqui está outra coisa a ter em mente: Por enquanto (PHP 5.2), a biblioteca DOP está com erros . Está cheio de insetos estranhos. Por exemplo: antes de armazenar a PDOStatementem uma variável, a variável deve ser unset()para evitar muitos erros. A maioria deles foi corrigida no PHP 5.3 e será lançada no início de 2009 no PHP 5.3, que provavelmente terá muitos outros bugs. Você deve se concentrar em usar o PDO para PHP 6.1 se desejar uma versão estável e usar o PDO para PHP 5.3 se desejar ajudar a comunidade.


2
Penso que os ganhos que o DOP oferece valem a pena compreender e contornar os erros. O próprio PHP está cheio de bugs muito agravantes, alguns dos quais não podemos nem trabalhar com eficiência, e ainda oferece muitos benefícios que nos levam a usá-lo em vez de outras opções.
27490 Brian Brian Hawhawk

11
Uhm, estranho, nunca experimentei nenhum bug com o DOP. E eu uso muito isso.
NikiC 23/01

Mysqli também tem bugs. Todo o software possui bugs.
Bill Karwin

10

Outra (notável) diferença notável sobre o DOP é que seu PDO::quote()método adiciona automaticamente as aspas anexas, enquanto mysqli::real_escape_string()(e similares) não:

PDO :: quote () coloca aspas ao redor da string de entrada (se necessário) e escapa caracteres especiais dentro da string de entrada, usando um estilo de aspas apropriado ao driver subjacente.


8

O PDO tornará muito mais fácil o dimensionamento se o seu site / aplicativo da Web realmente estiver sendo implementado, pois você pode configurar diariamente conexões Master e slave para distribuir a carga pelo banco de dados, além de o PHP estar caminhando para mudar para o DOP como padrão.

Informações DOP

Dimensionando um aplicativo Web


6

No sentido da velocidade de execução, o MySQLi vence, mas, a menos que você tenha um bom wrapper usando o MySQLi, suas funções que lidam com instruções preparadas são terríveis.

Ainda existem bugs nos meus, mas se alguém quiser, aqui está .

Então, resumindo, se você está procurando um ganho de velocidade, então MySQLi; se você quiser facilidade de uso, faça DOP.


2
em senso de velocidade, você poderia dar referências?
287 Julius F

8
Jonathen Robson fez uma comparação decente de velocidade dos dois em jonathanrobson.me/2010/06/mysqli-vs-pdo-benchmarks . Resumo: inserts - quase igual, selects - mysqli é ~ 2,5% mais rápido para instruções não preparadas / ~ 6,7% mais rápido para instruções preparadas. Dado o quão pequenas são as penalidades de desempenho, os recursos e a flexibilidade do uso PDOgeralmente superam o impacto no desempenho.
Adam

11
@ Adam Obrigado por ligar ao meu blog!
jnrbsn

@ daemonfire300 Isso é verdade, não há necessidade de benchmarks. O PDO envolve a biblioteca mysqli. Eu provavelmente iria acertar o ventilador se alguém pudesse provar que o DOP é mais rápido que o mysqli. :-D
Dyin

@jnrbsn você concorda com Adam sobre o que ele disse?
Basit 02/02

5

Pessoalmente, uso a DOP, mas acho que isso é principalmente uma questão de preferência.

O PDO possui alguns recursos que ajudam na injeção de SQL ( instruções preparadas ), mas se você for cuidadoso com o SQL, poderá conseguir isso também com o mysqli.

Mover para outro banco de dados não é uma razão para usar o DOP. Desde que você não use "recursos especiais do SQL", poderá alternar de um banco de dados para outro. No entanto, assim que você usa, por exemplo, "SELECT ... LIMIT 1", não é possível acessar o MS-SQL, onde está "SELECT TOP 1 ...". Portanto, isso é problemático de qualquer maneira.


22
O MySQLi preparou declarações.
Torre

5

Resposta editada.

Após ter alguma experiência com essas duas APIs, eu diria que existem 2 recursos de nível de bloqueio que tornam o mysqli inutilizável com instruções nativas preparadas.
Eles já foram mencionados em 2 respostas excelentes (ainda que subestimadas):

  1. Vinculando valores a um número arbitrário de espaços reservados
  2. Retornando dados como uma mera matriz

(ambos também mencionados nesta resposta )

Por alguma razão, o mysqli falhou com ambos.
Hoje em dia, houve algumas melhorias para o segundo ( get_result ), mas funciona apenas em instalações mysqlnd, significa que você não pode confiar nessa função em seus scripts.

No entanto, ele não tem vinculação por valor até hoje.

Portanto, há apenas uma opção: DOP

Todos os outros motivos, como

  • espaços reservados nomeados (esse açúcar de sintaxe é superestimado)
  • suporte a diferentes bancos de dados (ninguém realmente o usou)
  • buscar no objeto (apenas açúcar inútil de sintaxe)
  • diferença de velocidade (não há nenhuma)

não são de nenhuma importância significativa.

Ao mesmo tempo, essas duas APIs carecem de alguns recursos realmente importantes , como

  • espaço reservado identificador
  • espaço reservado para os tipos de dados complexos para tornar a ligação dinâmica menos trabalhosa
  • código de aplicação mais curto.

Portanto, para cobrir as necessidades da vida real , é necessário criar sua própria biblioteca de abstração, com base em uma dessas APIs, implementando espaços reservados analisados ​​manualmente. Neste caso, eu preferiria o mysqli, pois possui um nível menor de abstração.


Finalmente alguém que sabe e não nega os fatos da vida ...
Ihsan

4

No meu script de benchmark , cada método é testado 10000 vezes e a diferença do tempo total para cada método é impressa. Você deve fazer isso em sua própria configuração, tenho certeza que os resultados variarão!

Estes são os meus resultados:

  • " SELECT NULL" -> PGO()mais rápido em ~ 0,35 segundos
  • " SHOW TABLE STATUS" -> mysqli()mais rápido em ~ 2,3 segundos
  • " SELECT * FROM users" -> mysqli()mais rápido em ~ 33 segundos

Nota: usando -> fetch_row () para mysqli, os nomes das colunas não são adicionados à matriz, não encontrei uma maneira de fazer isso no PGO. Mas mesmo se eu usar -> fetch_array (), o mysqli é um pouco mais lento, mas ainda mais rápido que o PGO (exceto para SELECT NULL).


17
O que é PGO? E mais rápido em 33 segundos ?! Eu acho isso muito difícil de acreditar ...
Alix Axel

3

Uma coisa que a DOP tem que o MySQLi não me agrada é a capacidade da PDO de retornar um resultado como um objeto de um tipo de classe especificado (por exemplo $pdo->fetchObject('MyClass')). O MySQLi fetch_object()retornará apenas um stdClassobjeto.


19
Na verdade, você pode especificar uma classe manualmente: "objeto mysqli_result :: fetch_object ([string $ class_name [, array $ params]])". stdClass é usado apenas se você não especificar nada.
Andrioid 4/09/10

-4

Há uma coisa a ter em mente.

O Mysqli não suporta a função fetch_assoc () que retornaria as colunas com chaves representando os nomes das colunas. É claro que é possível escrever sua própria função para fazer isso, não é muito longo, mas tive muita dificuldade em escrevê-la (para não-crentes: se lhe parecer fácil, tente por conta própria algum tempo e não t enganar :))



2
Estava implementando há mais tempo, mas sim, verifiquei o manual. Funciona com declarações preparadas? Eu duvido ...
mike

2
Na verdade, ele tem um apoio curiosamente parcial. Você pode buscar matrizes em consultas regulares, mas não em consultas parametrizadas: -!
Álvaro González

11
Por que não excluir uma resposta que está obviamente errada?
precisa saber é o seguinte

2
@MajidFouladpour - A resposta não está obviamente errada . Só está faltando algum contexto. O Mysqli não suporta totalmente a recuperação associativa de matrizes.
Álvaro González
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.