Introdução: aquele erro que dá vontade de fechar o navegador
Se você já escreveu uma consulta MySQL em PHP e de repente viu algo assim no navegador:
Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in /var/www/site/index.php on line 15...então você conhece esse sentimento. Parece que está tudo certo: conectou, escreveu a consulta, e o PHP grita com você em vermelho. É especialmente frustrante quando o código funciona no servidor local, mas não no servidor de hospedagem. Ou vice-versa.
Esse erro é um dos mais populares no Stack Overflow. Milhares de desenvolvedores (nós inclusive) bateram a cabeça no teclado tentando entender: «Por que o parâmetro 1 espera um resource, mas recebe um boolean?»
Neste artigo, não vamos apenas analisar a causa, mas percorrer o caminho completo: desde reproduzir o erro até corrigi-lo. E de quebra, veremos por que as funções antigas mysql_* já deveriam ser substituídas por PDO ou MySQLi modernos. Vamos lá!
Como o problema aparece na prática
Vamos simular uma situação. Você tem uma tabela users e quer exibir todos os usuários. O código foi escrito à moda antiga:
$link = mysql_connect('localhost', 'user', 'password');mysql_select_db('test');
$result = mysql_query("SELECT * FROM users");
while ($row = mysql_fetch_array($result)) { echo $row['name'] . '<br>';}Parece clássico. Mas se a tabela users não existir, ou houver um erro de sintaxe no SQL, o mysql_query() retornará não um resource, mas false. E então mysql_fetch_array() recebe um boolean em vez de um resource — daí o erro.
Na maioria das vezes, o problema está justamente na execução mal-sucedida da consulta. Mas vamos analisar todas as causas possíveis em ordem.
Causa nº1: A consulta SQL retornou false
Esta é a situação mais comum. mysql_query() retorna false se a consulta falhar. Por exemplo:
- A tabela não existe
- Nome de campo incorreto
- Erro de sintaxe no SQL
- Problemas com permissões de acesso
Como verificar? Basta adicionar uma verificação após a consulta:
$result = mysql_query("SELECT * FROM non_existent_table");
if (!$result) { die('Erro na consulta: ' . mysql_error());}
while ($row = mysql_fetch_array($result)) { // ...}Isso mostrará imediatamente qual é o problema. mysql_error() exibirá o texto do erro, por exemplo: "Table 'test.non_existent_table' doesn't exist".
Causa nº2: Perda de conexão com o banco de dados
Às vezes a conexão é interrompida (por exemplo, devido a timeout ou reinicialização do MySQL). Nesse caso, mysql_query() também retornará false. A solução é sempre verificar a conexão:
$link = mysql_connect('localhost', 'user', 'password');if (!$link) { die('Não foi possível conectar: ' . mysql_error());}Mas mesmo isso não é uma solução definitiva. É melhor usar funções que conseguem reconectar automaticamente — como MySQLi.
Causa nº3: Você está misturando funções mysql_* e mysqli_*
Outro caso comum. Você pode acidentalmente misturar duas bibliotecas diferentes. Por exemplo, conectar via mysqli_connect(), mas fazer a consulta com mysql_query(). Isso não funciona: mysql_query() espera um resource de mysql_connect(), não de mysqli_connect().
Aqui está um exemplo de confusão:
// Conexão via MySQLi$link = mysqli_connect('localhost', 'user', 'password', 'test');
// Mas consulta via mysql_* antiga$result = mysql_query("SELECT * FROM users"); // Erro!
while ($row = mysql_fetch_array($result)) { echo $row['name'];}A solução é manter-se em uma única biblioteca. Ou