Por que as funções mysql_* no PHP são um perigo: análise completa com exemplos

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução: da história ao problema

\n\n

Se você já programou em PHP e trabalhou com bancos de dados MySQL, certamente já viu código como mysql_connect() ou mysql_query(). Há uns 10 ou 15 anos, isso era o padrão de fato. Mas os tempos mudaram, e hoje usar as funções mysql_* é como tentar rodar o Windows 95 em um MacBook novo. Dá, mas por quê?

\n\n

No Stack Overflow, a pergunta “Por que não devo usar funções mysql_* no PHP?” acumulou milhares de visualizações e centenas de votos. Não é por acaso: o tema de segurança e boas práticas com bancos de dados é essencial para qualquer desenvolvedor. Neste artigo, vamos entender por que mysql_* não é apenas “antigo”, mas francamente perigoso, e mostrar o que usar no lugar.

\n\n

Problema nº 1: mysql_* foi completamente removido no PHP 7

\n\n

O motivo mais óbvio: a partir do PHP 5.5.0, as funções mysql_* foram marcadas como deprecated (obsoletas) e, no PHP 7.0, foram totalmente removidas. Se o seu servidor for atualizado para PHP 7+, todo o código que usa mysql_connect(), mysql_query() e similares simplesmente para de funcionar. Você receberá um erro fatal:

\n\n
Fatal error: Call to undefined function mysql_connect()
\n\n

Isso não é “talvez não funcione”, é uma falha garantida do site. Portanto, a primeira e principal razão é: compatibilidade. Mais cedo ou mais tarde, qualquer hospedagem atualizará o PHP, e seu projeto ficará em uma zona morta.

\n\n

Problema nº 2: falta de proteção contra SQL injection

\n\n

Vamos ver um código típico com mysql_*:

\n\n
<?php\n$connection = mysql_connect('localhost', 'usuario', 'senha');\nmysql_select_db('meu_banco', $connection);\n\n$username = $_POST['username'];\n$password = $_POST['password'];\n\n$query = "SELECT * FROM usuarios WHERE username = '$username' AND password = '$password'";\n$result = mysql_query($query, $connection);\n\nif (mysql_num_rows($result) > 0) {\n    echo "Bem-vindo!";\n} else {\n    echo "Usuário ou senha inválidos";\n}\n?>
\n\n

Parece inofensivo? Agora imagine que um invasor digite no campo username a seguinte string:

\n\n
admin' OR '1'='1
\n\n

A consulta se transforma em:

\n\n
SELECT * FROM usuarios WHERE username = 'admin' OR '1'='1' AND password = '...'
\n\n

E pronto — '1'='1' é sempre verdadeiro, então a consulta retorna o primeiro registro da tabela. O invasor acessa o sistema sem senha. Isso é um SQL injection clássico. As funções mysql_* não oferecem nenhum recurso interno para escapar dados — você precisa usar manualmente mysql_real_escape_string(), que também está obsoleto.

\n\n

Compare com as abordagens modernas, onde a proteção já vem embutida na arquitetura (falaremos disso a seguir).

\n\n

Problema nº 3: arquitetura ultrapassada e falta de suporte

\n\n

mysql_* é uma interface procedural que não suporta:

\n\n
    \n
  • Prepared statements — a principal ferramenta de proteção contra injeção.
  • \n
  • Estilo orientado a objetos — no PHP moderno, o padrão é trabalhar com objetos.
  • \n
  • Múltiplas consultas — não é possível executar vários comandos SQL em uma única chamada.
  • \n
  • Transações — embora possam ser simuladas, não há suporte nativo.
  • \n
  • Stored procedures — o trabalho com elas é extremamente complicado.
  • \n
\n\n

Além disso, a extensão mysql_* não recebe atualizações desde 2014. Os desenvolvedores do PHP simplesmente pararam de mantê-la. Isso significa que qualquer novo recurso do banco de dados, melhoria de segurança ou otimização — tudo isso passa longe de você.

\n\n

O que usar no lugar de mysql_*?

\n\n

O PHP tem duas alternativas modernas e com suporte ativo: MySQLi e PDO. Ambas oferecem prepared statements, suporte a transações e são muito mais seguras. Recomendamos o PDO por ser mais flexível e funcionar com diferentes bancos de dados. Veja um exemplo com PDO:

\n\n
<?php\n$pdo = new PDO('mysql:host=localhost;dbname=meu_banco', 'usuario', 'senha');\n$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);\n\n$stmt = $pdo->prepare('SELECT * FROM usuarios WHERE username = :username AND password = :password');\n$stmt->execute(['username' => $_POST['username'], 'password' => $_POST['password']]);\n\nif ($stmt->rowCount() > 0) {\n    echo "Bem-vindo!";\n} else {\n    echo "Usuário ou senha inválidos";\n}\n?>
\n\n

Perceba como os dados são passados separadamente da consulta, eliminando qualquer risco de SQL injection. Essa é a forma correta e segura de programar em PHP hoje.

\n\n

Conclusão: migre agora e evite dores de cabeça

\n\n

Se você ainda mantém código legado com mysql_*, a mensagem é clara: migre o quanto antes. Além de ser inseguro e sem suporte, o uso dessas funções impede que seu projeto aproveite os avanços do PHP moderno. Invista algumas horas para refatorar seu código para PDO ou MySQLi — seu futuro eu (e seus usuários) agradecerão.

\n\n

Gostou do artigo? Compartilhe com outros desenvolvedores e ajude a tornar a web um lugar mais seguro!

Blogs

Book Recommendations