Introducción: «Tu logo no funciona y la base de datos llora»
\n\nSi alguna vez has escrito un script en PHP que trabaja con MySQL, seguro te has topado con esta aterradora frase:
\nWarning: mysql_fetch_array() expects parameter 1 to be resource, boolean given.
Vamos a aclararlo de inmediato: esto no es el fin del mundo. Es solo una señal de PHP que dice: «¡Oye, no puedo obtener datos de lo que me diste!».
\n\nEn este tutorial analizaremos por qué ocurre el error mysql_fetch_array() expects parameter 1 to be resource, cómo solucionarlo y, lo más importante, cómo dejar de verlo de una vez por todas (spoiler: migrando a PDO o MySQLi).
Este artículo está escrito especialmente para pythonlib.ru — un portal educativo donde enseñamos a programar sin dolor. ¡Allá vamos!
\n\n¿Por qué PHP se queja del parámetro? (causas)
\n\nPara entender la raíz del problema, recordemos cómo funcionan las antiguas funciones mysql_* (sí, las que quedaron obsoletas desde PHP 5.5).
El código típico de un principiante se ve así:
\n// Conexión\n$link = mysql_connect('localhost', 'usuario', 'contraseña');\nmysql_select_db('test');\n\n// Consulta (con error)\n$result = mysql_query("SELECT * FROM usuarios WHERE id = '1");\n\n// Intento de leer\nwhile($row = mysql_fetch_array($result)) { // ¡Error!\n echo $row['nombre'];\n}\n\n¿Qué está mal aquí? ¡Todo! Pero lo principal: mysql_query() devolvió false, no un resource. ¿Por qué?
- \n
- Error de sintaxis en SQL — la comilla no está cerrada. \n
- No hay conexión a la BD —
mysql_connect()devolvió false. \n - No se seleccionó la base de datos —
mysql_select_db()falló. \n - La tabla no existe. \n
Cuando mysql_query() falla, devuelve false (tipo booleano), no un resource. Y tú intentas pasar false a mysql_fetch_array(), que espera un resource. ¡Conflicto! De ahí el error.
¿Qué funciones se ven afectadas?
\n- \n
mysql_fetch_array()\n mysql_fetch_assoc()\n mysql_fetch_row()\n mysql_num_rows()\n mysql_data_seek()\n
Todas lanzan el mismo mensaje: «expects parameter 1 to be resource».
\n\nSolución paso a paso (para código antiguo)
\n\nSi tienes un proyecto heredado y aún no puedes actualizar PHP (aunque te lo recomiendo encarecidamente), así puedes detectar y corregir el error.
\n\nPaso 1. Verifica la conexión
\n$link = mysql_connect('localhost', 'usuario', 'contraseña');\nif (!$link) {\n die('Error de conexión: ' . mysql_error());\n}\n\nPaso 2. Verifica la selección de la base de datos
\nif (!mysql_select_db('mi_base_de_datos')) {\n die('No se pudo seleccionar la BD: ' . mysql_error());\n}\n\nPaso 3. Realiza la consulta con verificación
\n$sql = "SELECT * FROM usuarios WHERE id = 1";\n$result = mysql_query($sql);\n\nif (!$result) {\n die('Error en la consulta: ' . mysql_error());\n}\n\n// Ahora sí se puede usar sin miedo\nwhile($row = mysql_fetch_assoc($result)) {\n echo $row['nombre'];\n}\n\n¿Ves la diferencia? Verificamos cada paso. Si mysql_query() devuelve false, morimos con un mensaje de error, en lugar de pasar false hacia adelante.
¿Por qué esto sigue funcionando? (contexto histórico)
\n\nEn Stack Overflow esta pregunta acumula miles de visitas. Y no es de extrañar: todavía muchos servidores ejecutan PHP 5.x, y un montón de tutoriales (incluso en YouTube) enseñan con mysql_*.
Pero recuerda de una vez por todas: la extensión mysql está obsoleta y fue eliminada en PHP 7.0. Si escribes código nuevo, usa mysqli o PDO.