En este proyecto vamos a desarrollar paso a paso una aplicación web completa utilizando HTML, CSS, PHP y MySQL. La temática elegida será una tienda online de cuencos tibetanos, llamada Sonido Interior.
El objetivo no es solamente crear una web bonita, sino entender cómo se construye una aplicación web real desde cero: primero diseñaremos la parte visual, después organizaremos el código con PHP, más adelante conectaremos la aplicación con una base de datos y finalmente prepararemos el proyecto para poder ejecutarlo en un hosting o dentro de un contenedor.
Este proyecto nos servirá para repasar y aprender conceptos fundamentales del desarrollo web backend con PHP.
1. Objetivo general del proyecto
Vamos a crear una tienda web sencilla donde se puedan consultar productos relacionados con cuencos tibetanos, meditación y sonoterapia.
La aplicación tendrá dos partes principales:
La primera será la parte pública, visible para cualquier visitante. En ella se podrá ver la página de inicio, consultar el catálogo de productos y acceder a información básica de la tienda.
La segunda será la parte administrativa, pensada para el propietario o administrador de la tienda. Desde esta zona se podrán añadir productos, consultar el listado de productos existentes, editar información y borrar productos.
Aunque al principio trabajaremos con páginas estáticas, poco a poco iremos añadiendo funcionalidad real mediante PHP y MySQL.
2. Tecnologías que vamos a utilizar
Durante el proyecto trabajaremos con varias tecnologías habituales en el desarrollo web.
Usaremos HTML para crear la estructura de las páginas. Con HTML definiremos los títulos, formularios, menús, tablas, tarjetas de productos y el resto de elementos visibles.
Usaremos CSS para dar estilo al proyecto. Definiremos colores, tamaños, márgenes, distribución de columnas, botones, tarjetas y diseño general de la web.
Usaremos PHP para programar la parte del servidor. PHP nos permitirá reutilizar partes comunes de la web, procesar formularios, conectarnos a la base de datos, trabajar con sesiones y generar contenido dinámico.
Usaremos MySQL o MariaDB como sistema de base de datos. Ahí guardaremos los productos, categorías, usuarios administradores, mensajes y otros datos necesarios.
También utilizaremos un servidor local, como XAMPP, MAMP, Laragon, Docker o una máquina Linux con Apache, PHP y MySQL instalados.
3. Resultado final esperado
Al terminar el proyecto tendremos una aplicación web funcional con las siguientes partes:
- Página de inicio.
- Catálogo público de productos.
- Página de login para administración.
- Panel administrativo.
- Formulario para añadir productos.
- Listado administrativo de productos.
- Edición de productos.
- Borrado de productos.
- Subida de una imagen por producto.
- Base de datos relacional.
- Código organizado mediante includes.
- Posibilidad de instalar el proyecto en un hosting o contenedor.
El resultado será una primera versión de una tienda online. No será todavía una tienda profesional completa con pagos reales, pero sí tendrá la estructura base de una aplicación web real.
4. Fase 1: análisis de la idea
Antes de empezar a programar, lo primero será entender qué queremos construir.

Nuestra tienda se llamará Sonido Interior y venderá productos como:
- Cuencos tibetanos pequeños.
- Cuencos tibetanos medianos.
- Cuencos tibetanos grandes.
- Cuencos grabados.
- Mazas.
- Cojines.
- Sets de meditación.
- Accesorios relacionados con la sonoterapia.
Esta fase es importante porque antes de escribir código debemos saber qué páginas necesita la web, qué datos manejará y qué funcionalidades tendrá.
En clase analizaremos las necesidades básicas de la aplicación y pensaremos qué información debe tener cada producto.
Por ejemplo, un producto podrá tener:
- Nombre.
- Descripción.
- Precio.
- Stock.
- Categoría.
- Imagen.
- Diámetro.
- Peso.
- Material.
- Nota musical.
- Procedencia.
- Estado activo o inactivo.
5. Fase 2: diseño del prototipo visual
Después de definir la idea, crearemos un prototipo visual de la aplicación.
El prototipo nos servirá como referencia antes de programar. No empezaremos directamente escribiendo código sin saber cómo queremos que se vea la web.
Diseñaremos varias pantallas principales:
- Home o página de inicio.
- Página de login.
- Página de alta de productos.
- Catálogo público.
- Listado administrativo de productos.
La home tendrá una estética tranquila y artesanal, con colores beige, dorados, marrones suaves y blanco roto. La intención es que el diseño encaje con la temática de bienestar, meditación y sonido.
En esta fase podremos usar herramientas como Figma para replicar el diseño y entender la distribución visual antes de pasar a HTML y CSS.

6. Fase 3: creación de la maqueta en HTML y CSS
Una vez tengamos claro el diseño, empezaremos a crear las páginas en HTML y CSS.
En esta fase todavía no usaremos base de datos. El objetivo será construir la estructura visual de la aplicación.
Crearemos páginas como:
index.htmlcatalogo.htmllogin.htmladmin-alta-producto.htmladmin-listado-productos.html
También crearemos una carpeta para los estilos:
css/estilos.css
Y una carpeta para las imágenes:
img/
Durante esta parte trabajaremos conceptos importantes de HTML y CSS:
- Estructura básica de una página HTML.
- Etiquetas semánticas.
- Formularios.
- Tablas.
- Tarjetas de producto.
- Menús de navegación.
- Botones.
- Imágenes.
- Organización visual mediante CSS.
- Diseño de una zona pública y una zona administrativa.
Esta fase es fundamental porque nos permite construir la parte visual sin mezclarnos todavía con la lógica de programación.
7. Fase 4: conversión del proyecto a PHP
Cuando las páginas HTML estén preparadas, convertiremos el proyecto a PHP.
Esto significa que cambiaremos archivos como:
index.htmlporindex.phpcatalogo.htmlporcatalogo.phplogin.htmlporlogin.php
La ventaja de usar PHP es que podremos dividir la web en partes reutilizables.
Por ejemplo, muchas páginas tendrán la misma cabecera, el mismo menú y el mismo pie de página. No tiene sentido copiar y pegar ese código en todos los archivos.
Para solucionarlo, crearemos una carpeta llamada:
includes/
Dentro colocaremos archivos comunes como:
header.phpmenu.phpmenu-admin.phpfooter.php
Después, desde cada página principal podremos incluir esos fragmentos de código usando PHP.
Ejemplo:
<?php include("includes/header.php"); ?>
<?php include("includes/menu.php"); ?>
<main>
<h1>Bienvenido a Sonido Interior</h1>
<p>Cuencos tibetanos artesanales para meditación y bienestar.</p>
</main>
<?php include("includes/footer.php"); ?>
Con esto aprenderemos uno de los usos más importantes de PHP al inicio: reutilizar partes comunes de una web.
8. Fase 5: organización de carpetas del proyecto
El proyecto debe estar bien organizado desde el principio.
Una posible estructura será la siguiente:
sonido-interior/
│
├── index.php
├── catalogo.php
├── login.php
├── admin-alta-producto.php
├── admin-listado-productos.php
│
├── includes/
│ ├── header.php
│ ├── menu.php
│ ├── menu-admin.php
│ └── footer.php
│
├── css/
│ └── estilos.css
│
├── img/
│ └── productos/
│
└── sql/
└── base_datos.sql
Más adelante añadiremos nuevos archivos para guardar, editar, borrar y consultar productos.
La organización es importante porque en un proyecto real no podemos tener todos los archivos mezclados sin ningún criterio.
9. Fase 6: diseño de la base de datos
Cuando ya tengamos la parte visual y la estructura básica en PHP, pasaremos a crear la base de datos.
La base de datos será la encargada de almacenar la información real del proyecto.
Crearemos una base de datos llamada, por ejemplo:
tienda_cuencos
Dentro de ella podremos tener varias tablas:
usuarioscategoriasproductosmensajespedidosdetalle_pedidocarritocarrito_producto
Para empezar, nos centraremos sobre todo en las tablas más importantes:
usuarioscategoriasproductos
La tabla usuarios almacenará los datos de los administradores.
La tabla categorias guardará las categorías de productos.
La tabla productos guardará la información de cada cuenco o accesorio.
10. Fase 7: creación de la tabla de productos
La tabla de productos será una de las más importantes del proyecto.
Podría tener una estructura similar a esta:
CREATE TABLE productos (
id_producto INT AUTO_INCREMENT PRIMARY KEY,
nombre VARCHAR(150) NOT NULL,
descripcion TEXT,
precio DECIMAL(10,2) NOT NULL,
stock INT NOT NULL,
imagen VARCHAR(255),
diametro DECIMAL(5,2),
peso DECIMAL(8,2),
material VARCHAR(100),
nota_musical VARCHAR(50),
procedencia VARCHAR(100),
activo BOOLEAN DEFAULT true,
fecha_alta DATETIME DEFAULT CURRENT_TIMESTAMP,
id_categoria INT,
FOREIGN KEY (id_categoria) REFERENCES categorias(id_categoria)
);
Con esta tabla podremos guardar la información de cada producto y luego mostrarla en la parte pública y administrativa.

11. Fase 8: conexión de PHP con MySQL
Para que PHP pueda trabajar con la base de datos, necesitaremos crear un archivo de conexión.
Este archivo se puede llamar:
includes/conexion.php
Dentro escribiremos los datos necesarios para conectarnos al servidor MySQL.
Ejemplo inicial:
<?php
$servidor = "localhost";
$usuario = "root";
$password = "";
$baseDatos = "tienda_cuencos";
$conexion = new mysqli($servidor, $usuario, $password, $baseDatos);
if ($conexion->connect_error) {
die("Error de conexión: " . $conexion->connect_error);
}
$conexion->set_charset("utf8");
?>
A partir de este momento, cualquier página que necesite consultar la base de datos podrá incluir este archivo.
Ejemplo:
<?php include("includes/conexion.php"); ?>
12. Fase 9: mostrar productos desde la base de datos
Cuando tengamos productos guardados en la base de datos, modificaremos el catálogo público.
Al principio, los productos estarán escritos directamente en HTML. Después, haremos que PHP los lea desde MySQL.
La página catalogo.php realizará una consulta parecida a esta:
$sql = "SELECT * FROM productos WHERE activo = 1";
$resultado = $conexion->query($sql);
Después recorreremos los resultados y mostraremos cada producto en una tarjeta.
Ejemplo básico:
while ($producto = $resultado->fetch_assoc()) {
echo "<article class='tarjeta-producto'>";
echo "<img src='img/productos/" . $producto["imagen"] . "' alt='" . $producto["nombre"] . "'>";
echo "<h3>" . $producto["nombre"] . "</h3>";
echo "<p>" . $producto["precio"] . " €</p>";
echo "</article>";
}
Con esto veremos una de las grandes ventajas de usar PHP: la página se genera automáticamente con los datos de la base de datos.
13. Fase 10: formulario de alta de productos
Después crearemos la página para añadir productos desde la zona administrativa.
La página será:
admin-alta-producto.php
El formulario tendrá campos como:
- Nombre.
- Descripción.
- Categoría.
- Precio.
- Stock.
- Diámetro.
- Peso.
- Material.
- Nota musical.
- Procedencia.
- Imagen.
El formulario enviará los datos mediante el método POST.
Ejemplo:
<form action="producto-guardar.php" method="POST" enctype="multipart/form-data">
<label>Nombre del producto</label>
<input type="text" name="nombre">
<label>Precio</label>
<input type="number" step="0.01" name="precio">
<label>Stock</label>
<input type="number" name="stock">
<label>Imagen del producto</label>
<input type="file" name="imagen">
<button type="submit">Guardar producto</button>
</form>
El atributo enctype="multipart/form-data" será necesario para poder subir imágenes.
14. Fase 11: guardar productos en la base de datos
El formulario de alta enviará los datos a un archivo llamado:
producto-guardar.php
Ese archivo recogerá los datos enviados por POST y realizará un INSERT en la base de datos.
Ejemplo simplificado:
$nombre = $_POST["nombre"];
$descripcion = $_POST["descripcion"];
$precio = $_POST["precio"];
$stock = $_POST["stock"];
$sql = "INSERT INTO productos (nombre, descripcion, precio, stock)
VALUES ('$nombre', '$descripcion', '$precio', '$stock')";
$conexion->query($sql);
Más adelante mejoraremos este código usando validaciones y consultas preparadas para evitar problemas de seguridad.
15. Fase 12: subida de imágenes
Cada producto tendrá una imagen principal.
Para subir imágenes trabajaremos con la variable especial de PHP:
$_FILES
Cuando el usuario seleccione una imagen en el formulario, PHP podrá recibirla y moverla a una carpeta del proyecto.
La carpeta recomendada será:
img/productos/
El proceso será:
- El usuario selecciona una imagen.
- El formulario envía el archivo al servidor.
- PHP recibe el archivo temporal.
- PHP mueve el archivo a
img/productos/. - Se guarda el nombre del archivo en la base de datos.
Ejemplo básico:
$nombreImagen = $_FILES["imagen"]["name"];
$rutaTemporal = $_FILES["imagen"]["tmp_name"];
$rutaDestino = "img/productos/" . $nombreImagen;
move_uploaded_file($rutaTemporal, $rutaDestino);
Después guardaremos $nombreImagen en la tabla productos.
16. Fase 13: listado administrativo de productos
Además del catálogo público, crearemos una página administrativa donde se puedan ver todos los productos en formato tabla.
La página será:
admin-listado-productos.php
Mostrará datos como:
- ID.
- Imagen.
- Nombre.
- Categoría.
- Precio.
- Stock.
- Estado.
- Acciones.
Las acciones principales serán:
- Editar.
- Borrar.
- Añadir nuevo producto.
Ejemplo de enlaces:
<a href="producto-editar.php?id=3">Editar</a>
<a href="producto-borrar.php?id=3">Borrar</a>
Estos enlaces enviarán el identificador del producto por la URL usando el método GET.
17. Fase 14: edición de productos
La edición permitirá modificar los datos de un producto ya existente.
Crearemos una página llamada:
producto-editar.php
Esta página recibirá el ID del producto mediante la URL.
Ejemplo:
producto-editar.php?id=3
Con ese ID, PHP consultará la base de datos, recuperará los datos actuales del producto y los mostrará dentro de un formulario.
Después, el formulario enviará los datos modificados a:
producto-actualizar.php
Ese archivo realizará una consulta UPDATE.
Ejemplo:
UPDATE productos
SET nombre = 'Cuenco tibetano mediano',
precio = 89.00,
stock = 5
WHERE id_producto = 3;
18. Fase 15: borrado de productos
También implementaremos la opción de borrar productos.
Podemos hacerlo de dos formas.
La primera forma es el borrado físico, que elimina el producto de la base de datos.
DELETE FROM productos WHERE id_producto = 3;
La segunda forma es el borrado lógico, que no elimina realmente el producto, sino que lo marca como inactivo.
UPDATE productos SET activo = false WHERE id_producto = 3;
En este proyecto es recomendable usar borrado lógico, porque es más parecido a lo que se hace en muchas aplicaciones reales. De esta forma, el producto deja de mostrarse en el catálogo, pero sus datos siguen guardados.
19. Fase 16: login de administración
La zona administrativa no debería estar abierta para cualquier usuario.
Por eso crearemos un sistema de login.
Tendremos una página:
login.php
Y una tabla de usuarios en la base de datos.
El formulario de login pedirá:
- Usuario o email.
- Contraseña.
Cuando el administrador introduzca sus datos, PHP comprobará si existe ese usuario y si la contraseña es correcta.
Si todo está bien, se creará una sesión.
Ejemplo:
session_start();
$_SESSION["usuario"] = $usuario;
$_SESSION["rol"] = "admin";
A partir de ese momento, el administrador podrá acceder a las páginas privadas.
20. Fase 17: protección de páginas privadas
No basta con tener una página de login. También debemos proteger las páginas administrativas.
Para ello crearemos un archivo:
includes/seguridad.php
Este archivo comprobará si existe una sesión iniciada.
Ejemplo:
<?php
session_start();
if (!isset($_SESSION["usuario"])) {
header("Location: login.php");
exit();
}
?>
Después incluiremos este archivo al principio de cada página privada.
Ejemplo:
<?php include("includes/seguridad.php"); ?>
Así evitaremos que alguien pueda entrar directamente escribiendo la URL de una página administrativa.
21. Fase 18: cierre de sesión
También necesitaremos una opción para cerrar sesión.
Crearemos un archivo:
logout.php
Este archivo destruirá la sesión y devolverá al usuario a la página de login o a la home.
Ejemplo:
<?php
session_start();
session_destroy();
header("Location: login.php");
exit();
?>
22. Fase 19: validaciones básicas
Una vez que la aplicación funcione, empezaremos a mejorarla con validaciones.
Validar significa comprobar que los datos que llegan al servidor tienen sentido.
Por ejemplo:
- Que el nombre del producto no esté vacío.
- Que el precio sea mayor que cero.
- Que el stock sea un número entero.
- Que la imagen tenga una extensión permitida.
- Que el usuario y la contraseña del login no estén vacíos.
Las validaciones son importantes porque nunca debemos confiar ciegamente en los datos que llegan desde un formulario.
23. Fase 20: mejora de seguridad con consultas preparadas
Al principio podemos hacer consultas SQL sencillas para entender el funcionamiento.
Pero después debemos mejorar la seguridad usando consultas preparadas.
Las consultas preparadas ayudan a evitar ataques de inyección SQL.
En lugar de meter directamente los datos dentro de la consulta, usamos parámetros.
Ejemplo orientativo:
$stmt = $conexion->prepare("INSERT INTO productos (nombre, precio, stock) VALUES (?, ?, ?)");
$stmt->bind_param("sdi", $nombre, $precio, $stock);
$stmt->execute();
Esto es más seguro y más profesional que concatenar directamente los valores dentro de una cadena SQL.
24. Fase 21: mejora de contraseñas
Las contraseñas no deben guardarse nunca en texto plano.
Para guardar contraseñas correctamente usaremos:
password_hash()
Y para comprobarlas:
password_verify()
Ejemplo para crear una contraseña cifrada:
$passwordCifrada = password_hash($password, PASSWORD_DEFAULT);
Ejemplo para comprobar una contraseña:
if (password_verify($passwordIntroducida, $passwordGuardada)) {
echo "Contraseña correcta";
}
Esta parte es fundamental para entender la seguridad básica de una aplicación web.
25. Fase 22: preparación para hosting
Cuando el proyecto funcione en local, veremos cómo prepararlo para subirlo a un hosting.
Para ello tendremos que revisar varias cosas:
- Que los archivos estén bien organizados.
- Que la base de datos esté exportada en un archivo
.sql. - Que el archivo de conexión tenga los datos correctos del hosting.
- Que las rutas de imágenes funcionen correctamente.
- Que las carpetas de subida tengan permisos adecuados.
- Que no subamos archivos innecesarios.
En un hosting real, los datos de conexión no suelen ser:
localhost
root
sin contraseña
Normalmente el proveedor nos dará:
- Servidor de base de datos.
- Nombre de la base de datos.
- Usuario de base de datos.
- Contraseña de base de datos.
Tendremos que modificar el archivo conexion.php con esos datos.
26. Fase 23: exportación e importación de la base de datos
Para mover el proyecto desde nuestro equipo local a un hosting, tendremos que exportar la base de datos.
Si usamos phpMyAdmin, el proceso será:
- Entrar en phpMyAdmin.
- Seleccionar la base de datos.
- Ir a la opción exportar.
- Guardar el archivo
.sql.
Después, en el hosting:
- Crear una nueva base de datos.
- Entrar en phpMyAdmin del hosting.
- Importar el archivo
.sql. - Revisar que las tablas y datos se han creado correctamente.
Esta parte nos permitirá entender que una aplicación web no está formada solo por archivos PHP, sino también por una base de datos que debe acompañar al proyecto.
27. Fase 24: despliegue en un contenedor Docker
Además del hosting tradicional, también veremos la posibilidad de ejecutar el proyecto usando contenedores.
Docker nos permite levantar un entorno completo con Apache, PHP y MySQL sin instalar todo manualmente en el sistema.
Una estructura sencilla podría tener:
- Un contenedor para Apache con PHP.
- Un contenedor para MySQL o MariaDB.
- Un contenedor opcional para phpMyAdmin.
El proyecto podría tener un archivo:
docker-compose.yml
Con este archivo podríamos levantar todo el entorno usando un comando.
Ejemplo orientativo:
services:
web:
image: php:8.2-apache
ports:
- "8080:80"
volumes:
- ./src:/var/www/html
db:
image: mariadb:10.11
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: tienda_cuencos
MYSQL_USER: usuario
MYSQL_PASSWORD: usuario
phpmyadmin:
image: phpmyadmin
ports:
- "8081:80"
environment:
PMA_HOST: db
Con esta opción podríamos acceder a la web desde:
http://localhost:8080
Y a phpMyAdmin desde:
http://localhost:8081
En este caso, el servidor de base de datos dentro de conexion.php no sería localhost, sino el nombre del servicio de Docker:
$servidor = "db";
Esto es muy importante, porque dentro de Docker los contenedores se comunican entre ellos usando el nombre del servicio.
28. Fase 25: documentación final del proyecto
Al terminar el proyecto, cada alumno deberá documentar el trabajo realizado.
La documentación debería incluir:
- Descripción del proyecto.
- Tecnologías utilizadas.
- Capturas de pantalla.
- Estructura de carpetas.
- Explicación de la base de datos.
- Diagrama de base de datos.
- Explicación de las páginas públicas.
- Explicación de las páginas privadas.
- Explicación del CRUD.
- Problemas encontrados.
- Mejoras posibles.
- Conclusión personal.
Documentar el proyecto es importante porque en el desarrollo real no basta con que algo funcione. También hay que saber explicar cómo se ha construido y por qué se ha hecho de esa manera.
29. Posibles ampliaciones
Cuando la versión básica esté terminada, podremos añadir mejoras.
Algunas posibilidades son:
- Buscador de productos.
- Filtro por categoría.
- Página de detalle de producto.
- Carrito de compra.
- Registro de clientes.
- Gestión de pedidos.
- Mensajes de contacto.
- Panel con estadísticas.
- Paginación de productos.
- Validación avanzada de formularios.
- Mejora de seguridad.
- Diseño responsive para móviles.
- Uso de variables de entorno.
- Separación del código en funciones.
- Primer acercamiento a arquitectura MVC.
Estas ampliaciones nos permitirán convertir el proyecto en una aplicación cada vez más completa.
30. Qué aprenderemos con este proyecto
Este proyecto nos permitirá practicar muchos conceptos importantes.
Aprenderemos a transformar una idea en una aplicación web. Veremos cómo pasar de un prototipo visual a páginas HTML y CSS, y después cómo convertir esas páginas en una aplicación dinámica con PHP.
También aprenderemos a trabajar con formularios, recibir datos por POST, enviar datos por GET, consultar una base de datos, insertar registros, actualizar información y borrar datos.
Además, veremos cómo proteger una zona privada con sesiones, cómo subir imágenes al servidor y cómo preparar el proyecto para ejecutarlo fuera del entorno local.
El objetivo final es que cada alumno entienda el ciclo completo de desarrollo de una pequeña aplicación web: desde la idea inicial hasta su posible despliegue.
31. Conclusión
La tienda de cuencos tibetanos Sonido Interior será nuestro proyecto base para aprender desarrollo web con PHP.
A lo largo de las clases iremos construyendo la aplicación paso a paso. Empezaremos por lo visual, seguiremos con la organización del código, añadiremos base de datos, implementaremos funcionalidades reales y terminaremos preparando el proyecto para su publicación.
Este proyecto nos servirá como punto de partida para entender cómo funcionan muchas aplicaciones web reales.
La clave será avanzar poco a poco, comprender cada fase y no limitarnos a copiar código. Cada parte del proyecto tendrá un objetivo concreto y nos ayudará a construir una base sólida para proyectos más avanzados.










