Historia de un error: por qué mysql_* es cosa del pasado
\n\nImagina: estás escribiendo un sitio web en PHP, te conectas a una base de datos MySQL y usas la función conocida de la universidad mysql_query(). Todo funciona, el sitio vive, los usuarios están contentos. Pero un día notas una advertencia extraña en los registros: «Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future». Esto no es solo un regaño del intérprete, es una bandera roja que no se puede ignorar.
En Stack Overflow, la pregunta «Why shouldn't I use mysql_* functions in PHP?» ha acumulado miles de visitas y cientos de comentarios. Y no es casualidad. En este artículo analizaremos por qué las funciones mysql_* (mysql_connect, mysql_query, mysql_fetch_array y otras) se convirtieron en el enemigo número uno para los desarrolladores de PHP, mostraremos con ejemplos de código reales cómo reemplazarlas y daremos un plan de migración paso a paso.
\n\n¿Qué son mysql_* y por qué las eliminaron?
\n\nLa extensión mysql_* (MySQL original) apareció en PHP 2.0 en el lejano 1997. Era simple e intuitiva: llamabas a mysql_connect(), ejecutabas una consulta con mysql_query(), obtenías el resultado. Pero esta simplicidad tenía un lado oscuro.
A partir de PHP 5.5.0, todas las funciones mysql_* fueron marcadas como obsoletas (deprecated), y en PHP 7.0 fueron eliminadas por completo. Si intentas usar mysql_connect() en PHP 7+, obtendrás un error fatal: Call to undefined function mysql_connect(). La razón no es un capricho de los desarrolladores de PHP, sino problemas fundamentales de seguridad y arquitectura.
Tres razones principales para abandonar mysql_*
\n\n- \n
- Inyecciones SQL sin protección — las funciones no admiten consultas preparadas (prepared statements), lo que hace que el escape manual sea obligatorio, pero a menudo un paso olvidado. \n
- Arquitectura obsoleta — no hay soporte para estilo orientado a objetos, procedimientos almacenados, consultas múltiples ni transacciones. \n
- Falta de desarrollo — la extensión no se actualizó durante años, mientras MySQL cambiaba (por ejemplo, aparecieron nuevos tipos de datos, codificaciones, mecanismos de autenticación). \n
Ejemplo en vivo: cómo mysql_* destruye tu sitio web
\n\nVeamos el código clásico que todavía se encuentra en libros de texto antiguos y foros:
\n\n<?php\n// CÓDIGO OBSOLETO - ¡NO USAR!\n$link = mysql_connect('localhost', 'root', 'password');\nmysql_select_db('users_db', $link);\n\n$user_input = $_GET['username']; // el usuario ingresa: ' OR 1=1 --\n$query = "SELECT * FROM users WHERE username = '$user_input'";\n$result = mysql_query($query, $link);\n\nwhile ($row = mysql_fetch_assoc($result)) {\n echo "Hola, " . $row['username'] . "<br>";\n}\n?>\n\n¿Cuál es el problema? Si un atacante pasa al parámetro username el valor ' OR 1=1 --, la consulta se convierte en:
SELECT * FROM users WHERE username = '' OR 1=1 --\n\nEl doble guión -- comentará el resto de la consulta, y la condición 1=1 siempre es verdadera. Como resultado, obtendrás todos los usuarios de la base de datos, incluyendo contraseñas, correos electrónicos y otra información confidencial. Esto no es teoría, es una vulnerabilidad real que rompe miles de sitios web cada día.
Por supuesto, se puede usar mysql_real_escape_string(), pero:
- \n
- Los desarrolladores a menudo olvidan llamarlo. \n
- No protege contra todos los tipos de ataques (por ejemplo, ataques que utilizan codificaciones). \n
- El código se vuelve sucio y difícil de leer. \n
Con qué reemplazar mysql_*: dos enfoques modernos
\n\nEn el PHP moderno hay dos extensiones dignas para trabajar con MySQL: mysqli (MySQL Improved) y PDO (PHP Data Objects). Ambas sop