PHP sigue siendo uno de los lenguajes más utilizados para el desarrollo web, y uno de sus usos más comunes es interactuar con bases de datos. En este artículo, aprenderemos cómo listar datos de una base de datos MySQL utilizando técnicas modernas en PHP, siguiendo las mejores prácticas de conexión y mostrando los datos en una lista HTML.
Para este artículo preparé un ejemplo que consistirá en extraer el título y el año de lanzamiento de una tabla llamada tmovies
, que almacena información sobre películas. A continuación veremos los pasos a seguirm
Estructura de la tabla
El primer paso será crear la base de datos en la que incorporaremos nuestra tabla. Para este contamos con el comando CREATE
, como vemos a continuación:
CREATE DATABASE moviesdb;
Luego podremos seleccionar la base de datos y crear la tabla. Antes de avanzar, resulta fundamental definir la estructura de nuestra tabla en la base de datos. La tabla tmovies
tendrá los siguientes campos:
CREATE TABLE tmovies ( idmovie INT AUTO_INCREMENT PRIMARY KEY, title VARCHAR(255) NOT NULL, year YEAR NOT NULL );
Explicación de los campos:
idmovie
: es el identificador único de cada película, se autoincrementa para que no tengamos que asignarlo manualmente.title
: este es un dato fundamental, ya que es el título de la película. Para este caso, lo definimos como un campo de texto con una longitud máxima de 255 caracteres. También establecemos que no pueda ser nulo, ya que no debemos permitir valores vacíos.year
: mediante este dato vamos a definir el año en que la película fue lanzada. Es almacenado como un tipoYEAR
.
Datos de ejemplo
Vamos a insertar algunos datos en esta tabla para tener algo que listar:
INSERT INTO tmovies (title, year) VALUES ('Indiana Jones and the Last Crusade', 1989), ('The Matrix', 1999), ('Inception', 2010), ('Interstellar', 2014), ('The Godfather', 1972), ('Pulp Fiction', 1994);
El primer paso para listar datos de una base de datos MySQL en PHP es establecer una conexión. Hoy en día, se recomienda usar PDO (PHP Data Objects) para interactuar con bases de datos en lugar de funciones obsoletas como mysql_connect()
. PDO es seguro y flexible, ya que permite trabajar con diferentes bases de datos sin cambiar el código significativamente.
En el siguiente ejemplo veremos cómo crear una conexión a la base de datos con PDO:
<?php $host = 'localhost'; // Nombre del servidor de MySQL $db = 'moviesdb'; // Nombre de la base de datos $user = 'root'; // Usuario de MySQL $pass = ''; // Contraseña de MySQL (dejar en blanco si no tiene) try { // Creando una nueva instancia de PDO para la conexión $pdo = new PDO("mysql:host=$host;dbname=$db;charset=utf8mb4", $user, $pass); // Configuramos PDO para que lance excepciones en caso de errores $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch (PDOException $e) { // Capturamos cualquier error en la conexión echo "Error en la conexión a la base de datos: " . $e->getMessage(); } ?>
Explicación del código:
- Usamos el constructor
PDO
para conectarnos a MySQL. Le pasamos el host, nombre de la base de datos, el usuario y la contraseña. Estos datos deben modificarse según la configuración de cada conexión. También se puede trabajar con constantes y variables de entorno, según la configuración y planificación de cada proyecto. - Establecemos el charset para asegurar que se manejen correctamente los caracteres especiales. El charset puede variar dependiendo de la estructura que se haya definido y el set de caracteres elegido para crear la base o la tabla. En versiones modernas de MySQL o MariaDB se puede emplear
utf8mb4
. La diferencia entreutf8
yutf8mb4
es que el primero soporta hasta 3 bytes por carácter, mientras que conutf8mb4
tendremos soporte de hasta 4 bytes por carácter. Esto permite manejar cualquier carácter Unicode, incluyendo emojis y otros caracteres de 4 bytes. - Usamos
setAttribute()
para habilitar el modo de excepción. Esto nos permitirá manejar los errores de conexión de una manera más limpia.
Listar datos de la tabla tmovies
Una vez que hemos establecido la conexión, podemos proceder a listar los datos. Vamos a realizar una consulta SQL para obtener el título y el año de las películas almacenadas en la tabla tmovies
.
Consultar los datos
Para realizar la consulta y listar los datos, utilizamos la sentencia SELECT
de SQL combinada con el método query()
de PDO:
<?php try { // Consulta SQL para obtener los títulos y años de las películas $sql = "SELECT title, year FROM tmovies"; // Ejecutamos la consulta $stmt = $pdo->query($sql); // Comprobamos si hay resultados if ($stmt->rowCount() > 0) { // Iniciamos la lista HTML echo "<ul>"; // Recorremos cada fila del resultado while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { echo "<li>" . htmlspecialchars($row['title']) . " (" . $row['year'] . ")</li>"; } // Cerramos la lista HTML echo "</ul>"; } else { echo "No se encontraron películas."; } } catch (PDOException $e) { echo "Error al realizar la consulta: " . $e->getMessage(); } ?>
Explicación del código:
- La variable
$sql
contiene la consultaSELECT
que obtiene los títulos y años de las películas desde la tablatmovies
. - Usamos el método
query()
de PDO para ejecutar la consulta. - La función
rowCount()
verifica si hay filas en el resultado. - Dentro de un bucle
while
, usamosfetch(PDO::FETCH_ASSOC)
para obtener cada fila como un array asociativo. Luego, mostramos el título y el año de la película dentro de un elemento<li>
. - Usamos
htmlspecialchars()
para asegurarnos de que los datos se muestren de forma segura en el HTML.
Resultado en HTML
El código anterior generará una lista como esta en el navegador:
<ul> <li>Indiana Jones and the Last Crusade (1989)</li> <li>The Matrix (1999)</li> <li>Inception (2010)</li> <li>Interstellar (2014)</li> <li>The Godfather (1972)</li> <li>Pulp Fiction (1994)</li> </ul>
Este formato es fácil de leer y permite mostrar los datos de manera organizada.
PHP cierra automáticamente la conexión a la base de datos cuando el script termina de ejecutarse. Sin embargo, también podemos hacerlo explícitamente.
Uso de prepare()
para consultas seguras
Aunque el método query()
es conveniente, no es seguro cuando se manejan datos proporcionados por el usuario debido al riesgo de inyecciones SQL. Para evitar esto, es recomendable usar sentencias preparadas con el método prepare()
de PDO, que permite manejar de forma segura las entradas de datos.
Este tipo de sentencias permiten que PHP y MySQL manejen los datos de manera separada de la consulta SQL, lo que impide que un usuario malintencionado inyecte código SQL en las entradas. Primero, se «prepara» la consulta con parámetros marcadores, y luego se ejecuta vinculando los valores reales a esos marcadores.
Ventajas de Usar prepare()
- Seguridad. Al separar la estructura de la consulta de los datos, se reduce el riesgo de inyección SQL.
- Eficiencia. Si se ejecuta la misma consulta repetidamente con diferentes valores, la consulta se prepara una vez y luego se ejecuta con diferentes datos, lo que mejora el rendimiento.
- Claridad y mantenimiento. Hace que el código sea más claro y fácil de mantener, ya que permite la reutilización de la consulta con diferentes valores.
Cómo usar prepare()
Si quisiéramos usar una consulta que implique parámetros proporcionados por el usuario, como por ejemplo, buscar películas por el año de lanzamiento, podríamos implementar prepare()
y execute()
de la siguiente manera:
Ejemplo de código usando prepare()
Supongamos que queremos mostrar todas las películas lanzadas en un año específico introducido por el usuario. Usaríamos una sentencia preparada para prevenir inyecciones SQL:
<?php // Supongamos que el año es proporcionado por el usuario $year = $_GET['year']; // Ejemplo: 2010 try { // Preparamos la consulta SQL con un marcador de posición (:year) $sql = "SELECT title, year FROM tmovies WHERE year = :year"; // Preparamos la consulta $stmt = $pdo->prepare($sql); // Vinculamos el parámetro :year con el valor proporcionado por el usuario $stmt->bindParam(':year', $year, PDO::PARAM_INT); // Ejecutamos la consulta $stmt->execute(); // Verificamos si hay resultados if ($stmt->rowCount() > 0) { echo "<ul>"; // Iteramos sobre los resultados while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { echo "<li>" . htmlspecialchars($row['title']) . " (" . $row['year'] . ")</li>"; } echo "</ul>"; } else { echo "No se encontraron películas para el año " . htmlspecialchars($year); } } catch (PDOException $e) { echo "Error al realizar la consulta: " . $e->getMessage(); } ?>
Explicación del código:
prepare()
: preparamos la consulta SQL con un marcador:year
en lugar de incrustar directamente el valor.bindParam()
: asociamos el marcador:year
con el valor proporcionado por el usuario en$_GET['year']
. Este método asegura que el valor sea tratado correctamente como un entero (conPDO::PARAM_INT
), lo que elimina la posibilidad de inyecciones SQL.execute()
: una vez que los parámetros están vinculados, ejecutamos la consulta de forma segura.- Protección contra inyecciones SQL: si el usuario intenta ingresar algo malicioso en el parámetro
year
, como2010; DROP TABLE tmovies;
, no funcionaría porque el valor se trata como un dato y no como parte de la consulta SQL.
Conclusión
Listar datos de una base de datos MySQL usando PHP y PDO es una técnica moderna, segura y flexible. En este artículo, hemos visto cómo conectar a una base de datos, ejecutar una consulta y mostrar los resultados en una lista HTML. Este enfoque es ideal para proyectos que requieren mostrar información de manera dinámica, como catálogos, listas de usuarios, o en este caso, películas.
Utilizar buenas prácticas de seguridad ayuda a prevenir problemas. Una opción es emplear htmlspecialchars()
para evitar la inyección de código malicioso al mostrar datos en el navegador.
El uso de prepare()
es fundamental cuando se manejan entradas de usuario, ya que mejora significativamente la seguridad de la aplicación. En nuestro caso, si se necesitara filtrar las películas por algún parámetro dinámico, como el año, el uso de sentencias preparadas es una opción que puede resultar muy útil. Además de aumentar la seguridad, prepare()
mejora el rendimiento en casos de consultas repetitivas. Por tanto, siempre que requieran entradas dinámicas, es una buena opción usar prepare()
y bindParam()
o bindValue()
para ayudar a que la aplicación PHP esté protegida contra ataques SQL y sea más robusta.
Claro está que todas esta técnicas deben ser combinadas con una serie de medidas estratégicas y estructurales para brindar la mayor solidez y seguridad a desarrollos que se lleven a producción. El análisis detallado de cada etapa y aspecto de un proyecto es clave para su correcta implementación y mantenimiento posterior. La seguridad y escalabilidad de una aplicación o sitio web responden a una visión general, que incluye a las personas que participan, la implementación del código y también a los servidores y servicios que se utilicen.
Si te interesa saber más sobre el tema déjame un comentario o escríbeme un mensaje.
Más sobre Diseño y desarrollo Web
Deja una respuesta