Galería de Imágenes con PHP y MySQL

Este proyecto consiste en la creación de un sistema de galería de imágenes utilizando PHP, MySQL, HTML, CSS y JavaScript. La galería está diseñada para ser de acceso público, donde las imágenes se visualizan en una cuadrícula de 2 columnas. Las imágenes son almacenadas en una carpeta llamada uploads y se ajustan automáticamente a un tamaño de 500×500 píxeles.

El sistema incluye las siguientes características:

  1. Página de Galería Pública: Muestra todas las imágenes cargadas en una cuadrícula de 3 columnas. Cada imagen incluye un título y una descripción corta (máximo 50 caracteres).
  2. Subida de Imágenes: Los usuarios pueden subir imágenes mediante un formulario. Durante la carga, las imágenes se redimensionan automáticamente a 500×500 px para mantener la consistencia visual. Además, se les asocia un título y una breve descripción.
  3. Gestión de Imágenes: El sistema permite a los usuarios modificar el título y la descripción de las imágenes, así como eliminar las imágenes que ya no sean necesarias.
  4. Menú de Navegación: Se incluye un menú de navegación superior en todas las páginas para facilitar la navegación entre la galería y la página de carga de imágenes. El encabezado de ambas páginas es de color negro con texto blanco para darle un aspecto profesional.
  5. Base de Datos MySQL: Toda la información de las imágenes (nombre del archivo, título y descripción) se almacena en una base de datos llamada ejcrud5 con una tabla images. El sistema interactúa con la base de datos para cargar, modificar y eliminar imágenes.

Este sistema está diseñado para ser fácilmente ampliable, con un enfoque en la simplicidad y eficiencia, asegurando una experiencia de usuario fluida y una interfaz visual profesional.

1. Estructura del Proyecto

Primero, necesitas tener los siguientes archivos y carpetas en tu servidor:

/galeria
|-- /uploads          // Carpeta donde se guardarán las imágenes
|-- /css              // Carpeta para hojas de estilo
|-- config.php        // Archivo de conexión a la base de datos
|-- index.php         // Página de la galería
|-- uploads.php        // Página para la subida de imágenes
|-- delete.php        // Página para eliminar una imagen
|-- edit.php          // Página para modificar imagen y detalles
|-- styles.css        // Archivo CSS con estilo profesional

2. Creación de la Base de Datos

El nombre de la base de datos será ejcrud5. En MySQL, puedes crear la base de datos y la tabla de esta forma:

CREATE DATABASE ejcrud5;
USE ejcrud5;

CREATE TABLE images (
    id INT(11) AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(50),
    description VARCHAR(50),
    filename VARCHAR(255),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

3. Archivo de Conexión a la Base de Datos (config.php)

Este archivo establece la conexión a la base de datos:

<?php
// config.php
$servername = "localhost";
$username = "root";
$password = ""; // Cambia si tienes contraseña para MySQL
$dbname = "ejcrud5";

$conn = new mysqli($servername, $username, $password, $dbname);

// Check connection
if ($conn->connect_error) {
    die("Conexión fallida: " . $conn->connect_error);
}
?>

4. Página de la Galería (index.php)

Esta página mostrará las imágenes en una galería de 3 columnas, con el título y la descripción:

<?php
// Incluye el archivo de configuración para establecer la conexión con la base de datos.
include 'config.php';

// Define una consulta SQL para seleccionar todas las filas de la tabla 'images',
// ordenadas por la columna 'created_at' en orden descendente (las más recientes primero).
$sql = "SELECT * FROM images ORDER BY created_at DESC";

// Ejecuta la consulta en la base de datos usando la conexión ($conn) y almacena el resultado en $result.
$result = $conn->query($sql);
?>

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <!-- Establece el conjunto de caracteres como UTF-8 para soportar caracteres especiales (acentos, símbolos, etc.). -->
    
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!-- Define el viewport para que la página sea responsiva, adaptándose a diferentes tamaños de pantallas, especialmente dispositivos móviles. -->

    <link rel="stylesheet" href="css/styles.css">
    <!-- Enlaza la hoja de estilos CSS que se encuentra en la carpeta 'css'. Este archivo contiene los estilos visuales de la página. -->

    <title>Galería de Fotos</title>
    <!-- Define el título de la página, que aparecerá en la pestaña del navegador. -->
</head>
<body>

<div class="header">
    <!-- Sección del encabezado de la página, donde se muestra el título y el menú de navegación. -->

    <h1>Galería de Fotos</h1>
    <!-- Encabezado principal de la página con el título "Galería de Fotos". -->

    <nav>
        <!-- Barra de navegación que contiene los enlaces a las distintas páginas del sitio. -->

        <a href="index.php">Galería</a>
        <!-- Enlace a la página principal (index.php), donde se muestra la galería de fotos. -->

        <a href="upload.php">Subir Imágenes</a>
        <!-- Enlace a la página 'upload.php', que permite subir nuevas imágenes a la galería. -->
    </nav>
</div>

<div class="gallery-container">
    <!-- Contenedor que agrupa los elementos de la galería, es decir, las imágenes y su información asociada. -->

    <?php while($row = $result->fetch_assoc()): ?>
    <!-- Bucle 'while' en PHP que recorre cada fila del resultado de la consulta ($result). Cada fila se almacena en la variable $row como un array asociativo. -->
    
        <div class="gallery-item">
        <!-- Contenedor individual para cada imagen de la galería, donde se mostrarán la imagen, el título y la descripción. -->

            <img src="uploads/<?= $row['filename'] ?>" alt="<?= $row['title'] ?>">
            <!-- La etiqueta 'img' muestra la imagen en la página. 
            El atributo 'src' indica la ruta de la imagen, que se encuentra en la carpeta 'uploads' 
            y cuyo nombre de archivo se extrae de la columna 'filename' de la base de datos. 
            El atributo 'alt' proporciona un texto alternativo para la imagen, usando el título que está en la columna 'title'. -->

            <h3><?= $row['title'] ?></h3>
            <!-- Muestra el título de la imagen. El valor del título se extrae de la columna 'title' de la base de datos. -->

            <p><?= $row['description'] ?></p>
            <!-- Muestra la descripción de la imagen. El valor de la descripción se obtiene de la columna 'description' de la base de datos. -->

            <a href="edit.php?id=<?= $row['id'] ?>">Editar</a> 
            <!-- Enlace para editar la imagen. Redirige a 'edit.php' y pasa el 'id' de la imagen como parámetro en la URL. Esto permite identificar qué imagen se va a editar. -->

            | 
            <!-- Separador visual entre los enlaces de "Editar" y "Eliminar". -->

            <a href="delete.php?id=<?= $row['id'] ?>" onclick="return confirm('¿Estás seguro de eliminar esta imagen?')">Eliminar</a>
            <!-- Enlace para eliminar la imagen. Redirige a 'delete.php' pasando el 'id' de la imagen en la URL. 
            Al hacer clic, se muestra un cuadro de confirmación para evitar eliminar imágenes accidentalmente. 
            Si el usuario confirma la eliminación, se ejecuta la acción de eliminar. -->
        </div>
        <!-- Fin del contenedor de la imagen individual. -->

    <?php endwhile; ?>
    <!-- Fin del bucle 'while'. Este bucle continúa hasta que no queden más filas en el resultado de la consulta. -->

</div>
<!-- Fin del contenedor de la galería. Aquí se muestran todas las imágenes obtenidas de la base de datos. -->

</body>
</html>

Resumen de la explicación:

  1. Conexión a la base de datos: Se incluye el archivo config.php, que establece la conexión con la base de datos.
  2. Consulta SQL: Se realiza una consulta a la base de datos para obtener todas las imágenes de la tabla images, ordenadas por fecha de creación (created_at) en orden descendente.
  3. Bucle while en PHP: Se utiliza un bucle while para recorrer el resultado de la consulta y mostrar cada imagen con su título, descripción y opciones para editar o eliminar la imagen.
  4. HTML y estructura: Se utiliza HTML para estructurar la página, incluyendo el encabezado, la galería y un menú de navegación.
  5. CSS: El archivo styles.css enlazado le da el estilo visual a la página (aunque no está incluido aquí, se define en otro archivo).

5. Página de Subida de Imágenes (upload.php)

Esta página permite subir nuevas imágenes a la galería:

<?php
include 'config.php';
// Incluye el archivo de configuración 'config.php', que establece la conexión a la base de datos.

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    // Verifica si el formulario ha sido enviado a través del método POST.
    
    $title = $_POST['title'];
    $description = $_POST['description'];
    // Obtiene los datos enviados por el formulario: el título de la imagen y la descripción.

    // Subida de archivo
    $target_dir = "uploads/";
    // Establece la ruta del directorio donde se almacenarán las imágenes subidas.

    $target_file = $target_dir . basename($_FILES["image"]["name"]);
    // Combina el directorio con el nombre original del archivo subido para crear la ruta completa.

    $imageFileType = strtolower(pathinfo($target_file, PATHINFO_EXTENSION));
    // Obtiene la extensión del archivo (jpg, png, etc.) en minúsculas.

    // Validar tamaño de imagen
    $check = getimagesize($_FILES["image"]["tmp_name"]);
    // Verifica si el archivo es una imagen válida comprobando su tamaño.

    if ($check !== false && move_uploaded_file($_FILES["image"]["tmp_name"], $target_file)) {
        // Si el archivo es una imagen válida y se ha movido correctamente a la carpeta 'uploads', continúa con el proceso.

        // Redimensionar la imagen a 500x500 px
        $filename = basename($_FILES["image"]["name"]);
        // Guarda el nombre del archivo subido en la variable $filename.

        $sql = "INSERT INTO images (title, description, filename) VALUES ('$title', '$description', '$filename')";
        // Crea una consulta SQL para insertar en la base de datos el título, descripción y nombre del archivo.

        if ($conn->query($sql) === TRUE) {
            // Ejecuta la consulta y si se realiza correctamente, muestra un mensaje de éxito.
            echo "Imagen subida con éxito!";
        } else {
            // Si hay un error en la consulta SQL, muestra un mensaje de error.
            echo "Error: " . $sql . "<br>" . $conn->error;
        }
    } else {
        // Si la imagen no es válida o no se pudo subir, muestra un mensaje de error.
        echo "Error al subir la imagen.";
    }
}
?>

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <!-- Establece el conjunto de caracteres como UTF-8 para soportar caracteres especiales. -->
    
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!-- Define el viewport para dispositivos móviles, asegurando que la página se vea bien en pantallas pequeñas. -->
    
    <link rel="stylesheet" href="css/styles.css">
    <!-- Enlaza el archivo de estilos 'styles.css' ubicado en la carpeta 'css'. -->

    <title>Subir Imágenes</title>
    <!-- Define el título de la página, que aparecerá en la pestaña del navegador. -->
</head>
<body>

<div class="header">
    <h1>Subir Imagen</h1>
    <!-- Muestra el título principal de la página. -->

    <nav>
        <!-- Barra de navegación con enlaces a otras páginas. -->

        <a href="index.php">Galería</a>
        <!-- Enlace a la página principal de la galería de imágenes (index.php). -->

        <a href="upload.php">Subir Imágenes</a>
        <!-- Enlace a la página actual donde se suben las imágenes. -->
    </nav>
</div>

<form action="upload.php" method="post" enctype="multipart/form-data">
    <!-- Formulario para subir imágenes. El atributo 'enctype' asegura que el formulario pueda enviar archivos. -->

    <label for="title">Título:</label>
    <!-- Etiqueta para el campo del título. -->

    <input type="text" name="title" maxlength="50" required><br>
    <!-- Campo de entrada para el título de la imagen, con un máximo de 50 caracteres. Es obligatorio. -->

    <label for="description">Descripción:</label>
    <!-- Etiqueta para el campo de la descripción. -->

    <input type="text" name="description" maxlength="50" required><br>
    <!-- Campo de entrada para la descripción de la imagen, con un máximo de 50 caracteres. Es obligatorio. -->

    <label for="image">Selecciona una imagen:</label>
    <!-- Etiqueta para el campo de selección de imagen. -->

    <input type="file" name="image" accept="image/*" required><br>
    <!-- Campo de entrada para seleccionar la imagen. Solo permite archivos de imagen y es obligatorio. -->

    <button type="submit">Subir</button>
    <!-- Botón para enviar el formulario y subir la imagen. -->
</form>

</body>
</html>

Resumen del archivo upload.php:

  1. Procesamiento de la imagen:
    • Se valida que el formulario haya sido enviado mediante el método POST.
    • El archivo subido es verificado para asegurarse de que es una imagen válida.
    • Si la imagen es válida, se guarda en el directorio uploads/ y se inserta su información en la base de datos.
  2. Formulario HTML:
    • El formulario permite al usuario ingresar un título, una descripción, y seleccionar una imagen para subir.
    • El formulario usa el atributo enctype="multipart/form-data" para permitir la subida de archivos.
    • Se validan campos obligatorios para el título, descripción y archivo de imagen.
  3. Consulta a la base de datos:
    • Una vez que se sube la imagen, se inserta en la base de datos el título, descripción y nombre del archivo asociado.

6. Eliminar Imagen (delete.php)

Aquí se gestiona la eliminación de imágenes:

<?php
include 'config.php';
// Incluye el archivo 'config.php', que contiene la configuración para conectarse a la base de datos.

if (isset($_GET['id'])) {
    // Verifica si se ha recibido un parámetro 'id' mediante el método GET en la URL.
    
    $id = $_GET['id'];
    // Almacena el valor del 'id' recibido en la variable $id. Este ID identifica la imagen que se va a eliminar.

    // Obtener el nombre del archivo
    $sql = "SELECT filename FROM images WHERE id=$id";
    // Crea una consulta SQL para seleccionar el nombre del archivo ('filename') de la tabla 'images' donde el 'id' coincide con el valor pasado.

    $result = $conn->query($sql);
    // Ejecuta la consulta en la base de datos y almacena el resultado en la variable $result.

    $row = $result->fetch_assoc();
    // Convierte el resultado de la consulta en un array asociativo y lo almacena en $row. Esto permite acceder al nombre del archivo.

    // Eliminar archivo físico
    if (unlink('uploads/' . $row['filename'])) {
        // Usa la función 'unlink()' para eliminar el archivo físicamente del servidor. La ruta del archivo es 'uploads/' más el nombre de archivo obtenido de la base de datos.
        
        // Eliminar de la base de datos
        $sql = "DELETE FROM images WHERE id=$id";
        // Crea una consulta SQL para eliminar la fila de la tabla 'images' donde el 'id' coincide con el valor recibido.

        if ($conn->query($sql) === TRUE) {
            // Ejecuta la consulta SQL para eliminar la fila correspondiente en la base de datos. Si tiene éxito, procede a redirigir al usuario.
            
            header("Location: index.php");
            // Redirige al usuario a la página 'index.php' después de eliminar la imagen.
        } else {
            // Si ocurre un error al intentar eliminar el registro en la base de datos, se muestra un mensaje de error.
            echo "Error al eliminar imagen.";
        }
    }
    // Si la eliminación física del archivo falla, no se ejecuta la eliminación de la base de datos.
}
?>

Explicación completa:

  1. Verificación del ID:
    • Se verifica si se recibe un id en la URL mediante el método GET. Este id corresponde a la imagen que el usuario desea eliminar.
  2. Consulta para obtener el archivo:
    • Se ejecuta una consulta SQL para obtener el nombre del archivo de la base de datos basado en el id recibido.
  3. Eliminación física del archivo:
    • Se usa unlink() para eliminar físicamente el archivo del servidor desde la carpeta uploads/. Si la eliminación es exitosa, continúa con la eliminación en la base de datos.
  4. Eliminación de la base de datos:
    • Después de eliminar el archivo del sistema, se ejecuta una consulta SQL para eliminar el registro asociado en la tabla images de la base de datos.
  5. Redirección:
    • Si todo sale bien, el usuario es redirigido a index.php para volver a la galería.
  6. Manejo de errores:
    • Si la eliminación del archivo o el registro de la base de datos falla, se muestra un mensaje de error.

7. Editar Imagen (edit.php)

Esta página permite editar el título y la descripción de una imagen:

<?php
include 'config.php';
// Incluye el archivo 'config.php', que establece la conexión a la base de datos.

if (isset($_GET['id'])) {
    // Verifica si se ha pasado el parámetro 'id' a través del método GET en la URL.
    $id = $_GET['id'];
    // Almacena el valor del 'id' en la variable $id. Este 'id' se usará para identificar la imagen que se va a editar.

    if ($_SERVER['REQUEST_METHOD'] == 'POST') {
        // Verifica si el formulario fue enviado utilizando el método POST.

        $title = $_POST['title'];
        $description = $_POST['description'];
        // Captura los valores del formulario: el título y la descripción de la imagen.

        $sql = "UPDATE images SET title='$title', description='$description' WHERE id=$id";
        // Crea una consulta SQL para actualizar el título y la descripción de la imagen en la base de datos, donde el 'id' coincide con el valor recibido.

        if ($conn->query($sql) === TRUE) {
            // Si la consulta SQL para actualizar se ejecuta correctamente, redirige al usuario a la página principal (index.php).
            header("Location: index.php");
        } else {
            // Si hay un error al ejecutar la consulta, muestra un mensaje de error.
            echo "Error al actualizar.";
        }
    }

    $sql = "SELECT * FROM images WHERE id=$id";
    // Crea una consulta SQL para obtener todos los datos de la imagen con el 'id' especificado.

    $result = $conn->query($sql);
    // Ejecuta la consulta en la base de datos y guarda el resultado en la variable $result.

    $row = $result->fetch_assoc();
    // Convierte el resultado de la consulta en un array asociativo y lo guarda en $row. Este array contendrá los datos de la imagen, como el título y la descripción.
}
?>

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <!-- Define el conjunto de caracteres como UTF-8 para manejar caracteres especiales correctamente. -->

    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!-- Configura el viewport para hacer que la página sea responsive, asegurando que se vea correctamente en dispositivos móviles. -->

    <link rel="stylesheet" href="css/styles.css">
    <!-- Enlaza el archivo de estilos 'styles.css', que contiene la apariencia visual de la página. -->

    <title>Editar Imagen</title>
    <!-- Establece el título de la página como "Editar Imagen". -->
</head>
<body>

<div class="header">
    <h1>Editar Imagen</h1>
    <!-- Muestra el título de la página en el encabezado. -->

    <nav>
        <!-- Crea una barra de navegación con enlaces a otras páginas. -->
        <a href="index.php">Galería</a>
        <!-- Enlace a la página principal de la galería (index.php). -->

        <a href="upload.php">Subir Imágenes</a>
        <!-- Enlace a la página de subida de imágenes (upload.php). -->
    </nav>
</div>

<form action="edit.php?id=<?= $row['id'] ?>" method="post">
    <!-- Formulario para editar la imagen. El atributo 'action' establece que los datos serán enviados a la misma página 'edit.php', pasando el 'id' en la URL. El método 'post' se utiliza para enviar los datos de manera segura. -->

    <label for="title">Título:</label>
    <!-- Etiqueta para el campo del título. -->
    <input type="text" name="title" maxlength="50" value="<?= $row['title'] ?>" required><br>
    <!-- Campo de entrada para el título de la imagen. El valor por defecto es el título actual de la imagen, obtenido de la base de datos. El campo es obligatorio y tiene un límite de 50 caracteres. -->

    <label for="description">Descripción:</label>
    <!-- Etiqueta para el campo de la descripción. -->
    <input type="text" name="description" maxlength="50" value="<?= $row['description'] ?>" required><br>
    <!-- Campo de entrada para la descripción de la imagen. El valor por defecto es la descripción actual de la imagen, obtenida de la base de datos. El campo es obligatorio y tiene un límite de 50 caracteres. -->

    <button type="submit">Actualizar</button>
    <!-- Botón para enviar el formulario. Al hacer clic, se enviarán los datos para actualizar el registro en la base de datos. -->
</form>

</body>
</html>

Explicación general:

  1. PHP: Se verifica si se ha recibido un id en la URL para identificar la imagen que se va a editar. Si el formulario es enviado con el método POST, se actualizan los datos en la base de datos. Luego, se realiza una consulta SQL para obtener la información actual de la imagen antes de mostrarla en el formulario.
  2. HTML: El formulario permite editar el título y la descripción de la imagen. Los valores actuales de la imagen se precargan en los campos, de manera que el usuario pueda ver la información que está editando.

Este archivo se encarga de mostrar un formulario con los datos de una imagen seleccionada y permite al usuario actualizarla.

8. Estilos CSS (styles.css)

Para darle un estilo profesional a la página:

/* styles.css */
body {
    font-family: Arial, sans-serif;
    margin: 0;
    padding: 0;
    background-color: #f4f4f4;
    color: #333;
}

.header {
    background-color: #000;
    color: #fff;
    padding: 15px;
    text-align: center;
}

.header nav {
    margin-top: 10px;
}

.header nav a {
    color: #fff;
    margin: 0 15px;
    text-decoration: none;
    font-weight: bold;
}

.gallery-container {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 15px;
    padding: 20px;
}

.gallery-item {
    flex-basis: calc(33.333% - 30px);
    background-color: #fff;
    padding: 10px;
    border: 1px solid #ddd;
    text-align: center;
}

.gallery-item img {
    width: 100%;
    height: auto;
    max-width: 500px;
    max-height: 500px;
}

form {
    padding: 20px;
    max-width: 600px;
    margin: 0 auto;
    background-color: #fff;
    border: 1px solid #ddd;
}

input[type="text"], input[type="file"] {
    width: 100%;
    padding: 10px;
    margin-bottom: 15px;
    border: 1px solid #ddd;
    border-radius: 5px;
}

button {
    padding: 10px 15px;
    background-color: #000;
    color: #fff;
    border: none;
    border-radius: 5px;
    cursor: pointer;
}

button:hover {
    background-color: #333;
}

Conclusión

Con este sistema tendrás una galería de imágenes funcional con la capacidad de subir, editar y eliminar imágenes.

Descargar los archivos PHP

Facebook
Twitter
LinkedIn

Dejá un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *