Categoría: Programación

  • Taller de PHP: completa el código

    Taller de PHP: completa el código

    Indicaciones para el alumnado

    Copia cada bloque en un archivo con el nombre indicado. La estructura HTML ya está preparada. Escribe PHP en los lugares marcados con TODO; no cambies los nombres de los campos del formulario. Usa $_POST para leer los datos y htmlspecialchars() al mostrarlos en HTML. Prueba también qué ocurre si envías campos vacíos. Puedes consultar la documentación y usar IA, pero debes poder explicar cada línea que añadas.

    Ejercicio 1 — Recibir y mostrar un nombre (01_saludo.php)

    Objetivo: detectar el envío, leer un campo y mostrar una respuesta segura. Al abrir la página por primera vez no debe aparecer un saludo; si se envía un nombre vacío debe aparecer un aviso.

    <?php
    $nombre = '';
    $mensaje = '';
    
    // TODO 1: Comprueba que la petición utiliza el método POST.
    // Dentro de esa condición, lee $_POST['nombre'].
    // Elimina los espacios al principio y al final con trim().
    // Si falta el campo, utiliza una cadena vacía como valor inicial.
    
    // TODO 2: Si $nombre está vacío, guarda en $mensaje:
    // "Escribe tu nombre". Si no, crea un saludo usando $nombre.
    // No introduzcas HTML escrito por el usuario sin escapar.
    ?>
    <!doctype html>
    <html lang="es">
    <head>
        <meta charset="UTF-8">
        <title>Ejercicio 1: saludo</title>
    </head>
    <body>
        <h1>Saludo</h1>
        <form method="post" action="">
            <label for="nombre">Nombre:</label>
            <input id="nombre" name="nombre" type="text">
            <button type="submit">Enviar</button>
        </form>
    
        <?php // TODO 3: Muestra $mensaje dentro de un párrafo SOLO si contiene texto.
              // Escapa el contenido al imprimirlo en HTML. ?>
    </body>
    </html>

    Pruebas: Ana → saludo; → aviso; <script>alert(1)</script> → se ve como texto, sin ejecutarse.

    Ejercicio 2 — Validar edad y conservar los datos (02_edad.php)

    Objetivo: recoger dos campos, mostrar errores y conservar el nombre y la edad cuando el formulario se envía. Edad válida: entero de 0 a 120. El formulario también debe funcionar al abrirse sin enviar datos.

    <?php
    $nombre = '';
    $edad = '';
    $errores = [];
    $resultado = '';
    
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        // TODO 1: Lee nombre y edad de $_POST con ?? ''.
        // Aplica trim() a ambas cadenas.
    
        // TODO 2: Si el nombre está vacío, añade un mensaje a $errores.
        // Valida la edad como entero entre 0 y 120.
        // Pista: filter_var($edad, FILTER_VALIDATE_INT,
        //     ['options' => ['min_range' => 0, 'max_range' => 120]])
        // puede devolver 0, que es una edad válida: compara con === false.
    
        // TODO 3: Solo si $errores está vacío, crea $resultado:
        // "NOMBRE tiene EDAD años" (con los valores enviados).
    }
    ?>
    <!doctype html>
    <html lang="es">
    <head><meta charset="UTF-8"><title>Ejercicio 2: edad</title></head>
    <body>
        <h1>Registro sencillo</h1>
        <form method="post" action="">
            <label>Nombre:
                <input name="nombre" value="<?= htmlspecialchars($nombre, ENT_QUOTES, 'UTF-8') ?>">
            </label>
            <label>Edad:
                <input name="edad" value="<?= htmlspecialchars($edad, ENT_QUOTES, 'UTF-8') ?>">
            </label>
            <button type="submit">Comprobar</button>
        </form>
    
        <?php // TODO 4: Recorre $errores y muestra cada uno en un <p>.
              // Muestra $resultado si no está vacío.
              // Escapa cualquier dato mostrado en HTML. ?>
    </body>
    </html>

    Pruebas: edad 0 válida; 17 válida; -1, 121, 3.5, abc y campo vacío → error.

    Ejercicio 3 — Elegir un curso (03_curso.php)

    Objetivo: trabajar con un <select>, una lista de opciones admitidas y un resumen. Evita aceptar un valor enviado manualmente que no figure entre los cursos.

    <?php
    $cursos = [
        'php' => 'PHP',
        'linux' => 'Linux',
        'redes' => 'Redes'
    ];
    $nombre = '';
    $curso = '';
    $mensaje = '';
    
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        // TODO 1: Lee y recorta nombre y curso desde $_POST.
        // Usa ?? '' para los campos que puedan faltar.
    
        // TODO 2: Comprueba que el nombre no está vacío y que la clave
        // $curso existe en $cursos (array_key_exists()).
        // Si algún dato falla, guarda un mensaje de error.
        // Si ambos son válidos, guarda un resumen con el nombre
        // del alumno y el nombre legible del curso.
    }
    ?>
    <!doctype html>
    <html lang="es">
    <head><meta charset="UTF-8"><title>Ejercicio 3: curso</title></head>
    <body>
        <h1>Inscripción</h1>
        <form method="post" action="">
            <label>Nombre:
                <input name="nombre" value="<?= htmlspecialchars($nombre, ENT_QUOTES, 'UTF-8') ?>">
            </label>
            <label>Curso:
                <select name="curso">
                    <option value="">Selecciona uno</option>
                    <?php foreach ($cursos as $codigo => $etiqueta): ?>
                        <option value="<?= htmlspecialchars($codigo, ENT_QUOTES, 'UTF-8') ?>"
                            <?= $curso === $codigo ? 'selected' : '' ?>>
                            <?= htmlspecialchars($etiqueta, ENT_QUOTES, 'UTF-8') ?>
                        </option>
                    <?php endforeach; ?>
                </select>
            </label>
            <button type="submit">Inscribirse</button>
        </form>
        <?php // TODO 3: Muestra $mensaje si contiene texto. Escápalo. ?>
    </body>
    </html>

    Pruebas: el curso elegido permanece seleccionado después de enviar; sin nombre o sin curso aparece error; un valor de curso inexistente se rechaza.

    Ejercicio 4 — Casillas y cálculo de total (04_pedido.php)

    Objetivo: leer varias casillas con el mismo nombre, validar los códigos recibidos y sumar los precios. Si no se marca ninguna casilla, el pedido se rechaza.

    <?php
    $productos = [
        'teclado' => ['nombre' => 'Teclado', 'precio' => 25],
        'raton' => ['nombre' => 'Ratón', 'precio' => 15],
        'alfombrilla' => ['nombre' => 'Alfombrilla', 'precio' => 10]
    ];
    $seleccion = [];
    $error = '';
    $total = null;
    
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        // TODO 1: Obtén $_POST['productos'] ?? [].
        // Verifica que es un array; si no, guarda un error.
    
        // TODO 2: Si es un array, comprueba que se marcó al menos
        // un producto y que TODOS sus códigos existen en $productos.
        // Para validar cada código, puedes usar is_string() y
        // array_key_exists(). Si hay uno incorrecto, muestra error.
    
        // TODO 3: Solo si no hay errores, suma el precio de cada
        // producto elegido y guarda el resultado en $total.
        // Pista: comienza $total en 0 antes de sumar.
    }
    ?>
    <!doctype html>
    <html lang="es">
    <head><meta charset="UTF-8"><title>Ejercicio 4: pedido</title></head>
    <body>
        <h1>Pedido de material</h1>
        <form method="post" action="">
            <?php foreach ($productos as $codigo => $datos): ?>
                <label>
                    <input type="checkbox" name="productos[]"
                        value="<?= htmlspecialchars($codigo, ENT_QUOTES, 'UTF-8') ?>"
                        <?= in_array($codigo, $seleccion, true) ? 'checked' : '' ?>>
                    <?= htmlspecialchars($datos['nombre'], ENT_QUOTES, 'UTF-8') ?>:
                    <?= $datos['precio'] ?> €
                </label><br>
            <?php endforeach; ?>
            <button type="submit">Calcular</button>
        </form>
    
        <?php // TODO 4: Muestra $error si existe o, si el pedido
              // es válido, muestra "Total: ... €".
              // Recuerda que $total puede valer 0; usa !== null. ?>
    </body>
    </html>

    Pruebas: teclado + ratón → 40 €; todos → 50 €; ninguno → error. Prueba también qué ocurre si se envía manualmente un código de producto desconocido.

    Qué explicar en la entrega

    Para cada ejercicio, escribe dos o tres frases: qué datos recibe el servidor, qué validación aplicaste y qué comportamiento observaste en las pruebas. No entregues solo una captura del código.


    Ejercicio 5 — Buscar en una lista con GET (05_busqueda.php)

    Objetivo: entender los parámetros de la URL. Muestra solo las asignaturas cuyo nombre contiene el texto buscado, sin distinguir mayúsculas y minúsculas.

    <?php
    $asignaturas = ['Fundamentos de Hardware', 'Redes', 'Sistemas Operativos', 'PHP', 'Seguridad'];
    $busqueda = '';
    $coincidencias = [];
    $buscado = isset($_GET['q']);
    
    if ($buscado) {
        // TODO 1: Lee $_GET['q'] con ?? '' y quita espacios con trim().
        // Si no está vacío, recorre $asignaturas y añade a $coincidencias
        // las que contengan el texto; pista: stripos() !== false.
    }
    ?>
    <!doctype html>
    <html lang="es"><head><meta charset="UTF-8"><title>Buscar asignatura</title></head>
    <body>
    <h1>Buscar asignaturas</h1>
    <form method="get" action="">
        <input name="q" value="<?= htmlspecialchars($busqueda, ENT_QUOTES, 'UTF-8') ?>">
        <button type="submit">Buscar</button>
    </form>
    <?php if ($buscado): ?>
        <?php // TODO 2: Si la búsqueda está vacía, pide que se escriba algo.
              // Si no hay coincidencias, muestra "Sin resultados".
              // Si las hay, imprímelas en una lista <ul>, escapando cada nombre. ?>
    <?php endif; ?>
    </body></html>

    Pruebas: busca red, PHP, xxx y una cadena vacía. Observa cómo cambia la URL.

    Ejercicio 6 — Calculadora de dos números (06_calculadora.php)

    Objetivo: validar valores numéricos y elegir una operación sin aceptar operaciones desconocidas. Muestra los errores y el resultado solamente tras enviar el formulario.

    <?php
    $a = '';
    $b = '';
    $operacion = 'sumar';
    $error = '';
    $resultado = null;
    
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        // TODO 1: Lee a, b y operacion usando $_POST y ?? ''.
        // Comprueba con is_numeric() que a y b son números.
        // Comprueba que operacion es "sumar", "restar" o "dividir".
    
        // TODO 2: Si la operación es dividir y b vale 0, guarda un error.
        // Si todo es válido, calcula y guarda $resultado.
    }
    ?>
    <!doctype html>
    <html lang="es"><head><meta charset="UTF-8"><title>Calculadora</title></head>
    <body>
    <h1>Calculadora</h1>
    <form method="post" action="">
        <input name="a" value="<?= htmlspecialchars((string) $a, ENT_QUOTES, 'UTF-8') ?>">
        <select name="operacion">
            <option value="sumar" <?= $operacion === 'sumar' ? 'selected' : '' ?>>Sumar</option>
            <option value="restar" <?= $operacion === 'restar' ? 'selected' : '' ?>>Restar</option>
            <option value="dividir" <?= $operacion === 'dividir' ? 'selected' : '' ?>>Dividir</option>
        </select>
        <input name="b" value="<?= htmlspecialchars((string) $b, ENT_QUOTES, 'UTF-8') ?>">
        <button type="submit">Calcular</button>
    </form>
    <?php // TODO 3: Muestra $error si existe; en otro caso, muestra
          // $resultado si es distinto de null. El resultado puede ser 0. ?>
    </body></html>

    Pruebas: 8 / 2 → 4; 5 - 5 → 0; 8 / 0 → error; hola + 2 → error.

    Ejercicio 7 — Opción de entrega con radio (07_entrega.php)

    Objetivo: leer un botón de opción, validar que pertenece a los valores admitidos y conservar la selección.

    <?php
    $formas = ['recogida' => 'Recogida en tienda', 'envio' => 'Envío a domicilio'];
    $seleccion = '';
    $mensaje = '';
    
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        // TODO 1: Lee $_POST['entrega'] ?? ''.
        // Comprueba con array_key_exists() que es una clave de $formas.
        // Si no lo es, guarda un error; si lo es, crea el mensaje
        // "Forma de entrega: ..." con la etiqueta correspondiente.
    }
    ?>
    <!doctype html>
    <html lang="es"><head><meta charset="UTF-8"><title>Entrega</title></head>
    <body>
    <h1>Elige la entrega</h1>
    <form method="post" action="">
        <?php foreach ($formas as $codigo => $texto): ?>
            <label>
                <input type="radio" name="entrega"
                    value="<?= htmlspecialchars($codigo, ENT_QUOTES, 'UTF-8') ?>"
                    <?= $seleccion === $codigo ? 'checked' : '' ?>>
                <?= htmlspecialchars($texto, ENT_QUOTES, 'UTF-8') ?>
            </label>
        <?php endforeach; ?>
        <button type="submit">Confirmar</button>
    </form>
    <?php // TODO 2: Muestra $mensaje, si existe, en un párrafo escapado. ?>
    </body></html>

    Pruebas: ninguna opción → error; una opción → mensaje y opción conservada; valor desconocido enviado manualmente → error.

    Ejercicio 8 — Etiquetas con varias casillas (08_etiquetas.php)

    Objetivo: recibir un array de opciones, comprobar sus valores y mostrar las etiquetas elegidas en una lista.

    <?php
    $opciones = ['php' => 'PHP', 'sql' => 'SQL', 'html' => 'HTML', 'linux' => 'Linux'];
    $elegidas = [];
    $error = '';
    $validas = false;
    
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        // TODO 1: Lee $_POST['etiquetas'] ?? [].
        // Si no es un array, deja $elegidas vacío y guarda un error.
        // Si es un array, cópialo a $elegidas.
    
        // TODO 2: Exige al menos una etiqueta. Recorre $elegidas y
        // comprueba que cada elemento es string y clave de $opciones.
        // Si todo está bien, establece $validas en true.
    }
    ?>
    <!doctype html>
    <html lang="es"><head><meta charset="UTF-8"><title>Etiquetas</title></head>
    <body>
    <h1>Tecnologías que conoces</h1>
    <form method="post" action="">
        <?php foreach ($opciones as $codigo => $etiqueta): ?>
            <label>
                <input type="checkbox" name="etiquetas[]"
                    value="<?= htmlspecialchars($codigo, ENT_QUOTES, 'UTF-8') ?>"
                    <?= in_array($codigo, $elegidas, true) ? 'checked' : '' ?>>
                <?= htmlspecialchars($etiqueta, ENT_QUOTES, 'UTF-8') ?>
            </label>
        <?php endforeach; ?>
        <button type="submit">Enviar</button>
    </form>
    <?php // TODO 3: Si hay $error, muéstralo. Si $validas es true,
          // crea una lista <ul> con los nombres de $opciones elegidas.
          // Escapa los textos al imprimirlos. ?>
    </body></html>

    Pruebas: ninguna, una y varias opciones; un código que no existe debe producir error.

    Ejercicio 9 — Comentario con límite de longitud (09_comentario.php)

    Objetivo: procesar un <textarea> y contar caracteres. Un comentario válido tiene entre 10 y 300 caracteres tras quitar espacios en los extremos.

    <?php
    $comentario = '';
    $error = '';
    $guardado = false;
    
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        // TODO 1: Lee $_POST['comentario'] ?? '' y usa trim().
        // Calcula su longitud con mb_strlen() si está disponible.
        // Si no lo está, utiliza strlen() e indica al profesor
        // que esta alternativa cuenta bytes en textos UTF-8.
    
        // TODO 2: Si la longitud queda fuera de 10..300, guarda
        // un error. Si es válida, establece $guardado en true.
    }
    ?>
    <!doctype html>
    <html lang="es"><head><meta charset="UTF-8"><title>Comentario</title></head>
    <body>
    <h1>Deja un comentario</h1>
    <form method="post" action="">
        <label for="comentario">Comentario:</label><br>
        <textarea id="comentario" name="comentario" rows="5" cols="45"><?= htmlspecialchars($comentario, ENT_QUOTES, 'UTF-8') ?></textarea><br>
        <button type="submit">Enviar</button>
    </form>
    <?php // TODO 3: Muestra el error o, si $guardado es true,
          // muestra el comentario dentro de un <p>.
          // Escapa antes de imprimir y utiliza nl2br() si quieres
          // conservar los saltos de línea visualmente. ?>
    </body></html>

    Pruebas: 9, 10, 300 y 301 caracteres; añade un salto de línea y texto con <b>.

    Ejercicio 10 — Comprobar una dirección de correo (10_correo.php)

    Objetivo: validar un correo sin enviarlo ni guardarlo. Muestra también el nombre del dominio tras la @ cuando sea válido.

    <?php
    $correo = '';
    $error = '';
    $dominio = '';
    $valido = false;
    
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        // TODO 1: Lee y recorta $_POST['correo'] ?? ''.
        // Valida con filter_var($correo, FILTER_VALIDATE_EMAIL).
        // Si falla, establece $error.
    
        // TODO 2: Si es válido, separa el correo por '@' con explode()
        // y guarda el dominio en $dominio. Activa $valido.
    }
    ?>
    <!doctype html>
    <html lang="es"><head><meta charset="UTF-8"><title>Correo</title></head>
    <body>
    <h1>Comprobar correo</h1>
    <form method="post" action="">
        <input name="correo" type="text"
            value="<?= htmlspecialchars($correo, ENT_QUOTES, 'UTF-8') ?>">
        <button type="submit">Comprobar</button>
    </form>
    <?php // TODO 3: Muestra $error o "Correo válido. Dominio: ...".
          // Escapa el dominio antes de mostrarlo. ?>
    </body></html>

    Pruebas: vacío, ana, ana@ejemplo.test y un correo con espacios alrededor.

    Ejercicio 11 — Precio con descuento mediante función (11_descuento.php)

    Objetivo: crear una función propia y llamarla desde el procesamiento del formulario. Porcentaje admitido: de 0 a 100.

    <?php
    // TODO 1: Crea la función aplicarDescuento(float $precio, float $porcentaje): float.
    // Debe devolver el precio después de restarle el porcentaje indicado.
    
    $precio = '';
    $porcentaje = '';
    $error = '';
    $precioFinal = null;
    
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        // TODO 2: Lee precio y porcentaje desde $_POST con ?? ''.
        // Verifica que ambos son numéricos. Precio no puede ser negativo;
        // porcentaje debe estar entre 0 y 100.
        // Si hay un dato incorrecto, guarda un mensaje en $error.
    
        // TODO 3: Cuando los datos sean válidos, convierte a float,
        // llama a aplicarDescuento() y guarda $precioFinal.
    }
    ?>
    <!doctype html>
    <html lang="es"><head><meta charset="UTF-8"><title>Descuento</title></head>
    <body>
    <h1>Calcular descuento</h1>
    <form method="post" action="">
        <label>Precio: <input name="precio" value="<?= htmlspecialchars((string) $precio, ENT_QUOTES, 'UTF-8') ?>"></label>
        <label>Descuento (%): <input name="porcentaje" value="<?= htmlspecialchars((string) $porcentaje, ENT_QUOTES, 'UTF-8') ?>"></label>
        <button type="submit">Calcular</button>
    </form>
    <?php // TODO 4: Muestra el error o el precio final con
          // number_format($precioFinal, 2, ',', '.') cuando no sea null. ?>
    </body></html>

    Pruebas: 100 y 20 → 80,00; 100 y 100 → 0,00; descuento 101 o precio negativo → error.

    Ejercicio 12 — Guardar una nota en un archivo (12_notas.php)

    Objetivo: añadir notas a un archivo de texto y volver a leerlas. Usa una nota por línea y evita que los saltos de línea del formulario creen entradas adicionales.

    <?php
    $ruta = __DIR__ . '/notas.txt';
    $nota = '';
    $mensaje = '';
    $contenido = '';
    
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        // TODO 1: Lee $_POST['nota'] ?? '' y aplica trim().
        // Rechaza el texto vacío. Sustituye \r y \n por espacios
        // antes de guardar, para mantener una nota por línea.
    
        // TODO 2: Añade la nota al archivo con file_put_contents(),
        // FILE_APPEND y LOCK_EX; añade PHP_EOL al final.
        // Comprueba el resultado con === false. Si falla, muestra error;
        // si funciona, muestra "Nota guardada".
    }
    
    // TODO 3: Si notas.txt existe, lee su contenido con file_get_contents().
    // Si la lectura falla, muestra un error y deja $contenido vacío.
    ?>
    <!doctype html>
    <html lang="es"><head><meta charset="UTF-8"><title>Notas</title></head>
    <body>
    <h1>Bloc de notas</h1>
    <form method="post" action="">
        <label>Nota: <input name="nota" value="<?= htmlspecialchars($nota, ENT_QUOTES, 'UTF-8') ?>"></label>
        <button type="submit">Guardar</button>
    </form>
    <?php // TODO 4: Muestra $mensaje y $contenido con HTML escapado.
          // Para que los saltos del archivo se vean, puedes usar nl2br()
          // DESPUÉS de htmlspecialchars(). ?>
    </body></html>

    Pruebas: guarda dos notas, recarga la página y verifica que siguen ahí; envía una nota vacía. El directorio donde está 12_notas.php debe permitir la escritura del archivo notas.txt.

    Ejercicio 13 — Contar visitas con sesión (13_sesion.php)

    Objetivo: usar $_SESSION para mantener un contador entre peticiones y reiniciarlo desde un formulario.

    <?php
    session_start(); // Debe ejecutarse antes de enviar HTML.
    
    // TODO 1: Si no existe $_SESSION['visitas'], inicialízala en 0.
    
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        // TODO 2: Si $_POST['accion'] ?? '' es "reiniciar",
        // pon $_SESSION['visitas'] a 0.
    } else {
        // TODO 3: Incrementa el contador en cada carga GET.
    }
    
    $visitas = $_SESSION['visitas'] ?? 0;
    ?>
    <!doctype html>
    <html lang="es"><head><meta charset="UTF-8"><title>Sesión</title></head>
    <body>
    <h1>Contador de visitas</h1>
    <p>Visitas: <?= (int) $visitas ?></p>
    <form method="post" action="">
        <input type="hidden" name="accion" value="reiniciar">
        <button type="submit">Reiniciar</button>
    </form>
    </body></html>

    Pruebas: recarga tres veces, reinicia y vuelve a recargar. Explica qué cuenta el ejercicio: cargas GET dentro de la misma sesión, no usuarios distintos.

    Ejercicio 14 — Subir una imagen con $_FILES (14_subida.php)

    Objetivo: recibir un fichero de un formulario, revisar el error de subida y guardarlo de forma segura. Solo se admiten imágenes JPEG o PNG de 2 MB como máximo. Este ejercicio requiere que PHP pueda crear la carpeta subidas junto al archivo.

    <?php
    $mensaje = '';
    $nombreGuardado = '';
    $directorio = __DIR__ . '/subidas';
    
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        // TODO 1: Comprueba que existe $_FILES['imagen'] y que
        // $_FILES['imagen']['error'] === UPLOAD_ERR_OK.
        // Si falta el archivo o PHP informa de otro error, guarda
        // un mensaje de error y no intentes moverlo.
    
        // TODO 2: Si no hubo error, comprueba que 'size' es mayor
        // que 0 y no supera 2 * 1024 * 1024 bytes.
        // Obtén la ruta temporal desde $_FILES['imagen']['tmp_name'].
        // NO confíes en $_FILES['imagen']['type'] ni en la extensión
        // original: detecta el MIME real con
        // (new finfo(FILEINFO_MIME_TYPE))->file($rutaTemporal).
        // Acepta solo image/jpeg e image/png.
    
        // TODO 3: Si el archivo es válido, crea $directorio con
        // mkdir($directorio, 0755, true) cuando no exista.
        // Comprueba también que la carpeta existe antes de mover.
        // Genera un nombre nuevo con bin2hex(random_bytes(16)):
        // añade '.jpg' para JPEG o '.png' para PNG.
        // NO uses el nombre original enviado por el navegador.
    
        // TODO 4: Mueve el fichero con move_uploaded_file()
        // a $directorio . '/' . $nombreGuardado.
        // Comprueba si devuelve true. Guarda en $mensaje
        // "Imagen subida" si va bien o un error si falla.
    }
    ?>
    <!doctype html>
    <html lang="es"><head><meta charset="UTF-8"><title>Subida de imagen</title></head>
    <body>
    <h1>Subir imagen</h1>
    <form method="post" action="" enctype="multipart/form-data">
        <label for="imagen">Selecciona una imagen JPEG o PNG:</label>
        <input id="imagen" name="imagen" type="file" accept="image/jpeg,image/png">
        <button type="submit">Subir</button>
    </form>
    <?php // TODO 5: Muestra $mensaje, escapándolo.
          // Si $nombreGuardado no está vacío Y la subida funcionó,
          // muestra el nombre nuevo del archivo también escapado.
          // No crees una URL pública de las imágenes en este ejercicio. ?>
    </body></html>

    Pruebas: sube JPEG, PNG, TXT, imagen mayor de 2 MB y formulario sin archivo. Comprueba los nombres nuevos en subidas. El atributo accept ayuda al navegador, pero la validación verdadera debe hacerse en PHP.

    Criterios comunes de corrección para los diez ejercicios

    • El archivo abre sin errores de sintaxis y la primera carga no produce avisos por índices inexistentes.
    • El resultado esperado aparece únicamente cuando se envían datos adecuados.
    • Los datos que llegan del formulario se validan y los textos mostrados en HTML se escapan.
    • El alumno entrega el código completado y evidencia de al menos dos pruebas por ejercicio, incluyendo un error de entrada.
  • Proyecto web en PHP orientado a objetos: tienda de cuencos tibetanos

    Proyecto web en PHP orientado a objetos: tienda de cuencos tibetanos

    En este proyecto vamos a desarrollar una aplicación web completa utilizando PHP orientado a objetos, MySQL, HTML y CSS. La temática será una tienda online de cuencos tibetanos llamada Sonido Interior.

    Este proyecto es una evolución del proyecto inicial realizado con PHP básico. En la primera versión trabajamos con páginas PHP sencillas, formularios, includes, conexión directa a base de datos y consultas SQL escritas en cada archivo.

    En esta nueva versión vamos a dar un paso más importante: organizaremos el código mediante clases, separaremos responsabilidades y construiremos una estructura más cercana a la que se utiliza en aplicaciones web reales.

    El objetivo no es complicar el proyecto sin necesidad, sino aprender a programar de forma más ordenada, reutilizable y mantenible.


    1. Objetivo general del proyecto

    Vamos a crear una tienda web de cuencos tibetanos con una parte pública y una parte administrativa.

    La parte pública permitirá ver la página de inicio, consultar el catálogo de productos y visualizar información de la tienda.

    La parte administrativa permitirá iniciar sesión, añadir productos, listar productos, editar productos y borrar productos.

    La diferencia principal respecto a la versión anterior será la forma de organizar el código.

    En lugar de escribir toda la lógica directamente en archivos como producto-guardar.php, producto-editar.php o catalogo.php, crearemos clases encargadas de realizar esas tareas.

    Por ejemplo, tendremos clases como:

    • Producto
    • Categoria
    • Usuario
    • Conexion
    • ProductoDAO
    • CategoriaDAO
    • UsuarioDAO

    Con esto empezaremos a trabajar una arquitectura más limpia y profesional.


    2. Qué significa usar programación orientada a objetos

    La programación orientada a objetos, o POO, es una forma de programar basada en clases y objetos.

    Una clase es como un molde. Define qué datos tendrá un elemento y qué acciones podrá realizar.

    Un objeto es una instancia concreta de una clase.

    Por ejemplo, en nuestro proyecto podemos tener una clase Producto.

    Esa clase representa cualquier producto de la tienda.

    class Producto {
    private $idProducto;
    private $nombre;
    private $descripcion;
    private $precio;
    private $stock;
    private $imagen;
    }

    Después, un cuenco tibetano concreto sería un objeto de esa clase.

    $producto = new Producto();

    La ventaja de este enfoque es que el código queda mejor organizado. En lugar de trabajar con variables sueltas y consultas repartidas por muchas páginas, agrupamos la información y el comportamiento en clases.


    3. Diferencia entre la versión básica y la versión POO

    En la versión básica del proyecto, la conexión a la base de datos y las consultas pueden estar escritas directamente dentro de las páginas.

    Por ejemplo:

    include("includes/conexion.php");

    $sql = "SELECT * FROM productos";
    $resultado = $conexion->query($sql);

    En la versión orientada a objetos, intentaremos que la página no tenga que saber cómo se hace la consulta.

    La página pedirá los productos a una clase especializada:

    $productoDAO = new ProductoDAO();
    $productos = $productoDAO->obtenerTodos();

    La página solo se encargará de mostrar los datos. La clase ProductoDAO será la encargada de hablar con la base de datos.

    Esto hace que el proyecto sea más fácil de mantener, ampliar y corregir.


    4. Tecnologías que vamos a utilizar

    En esta versión seguiremos utilizando las mismas tecnologías principales:

    • HTML.
    • CSS.
    • PHP.
    • MySQL o MariaDB.
    • Apache.
    • phpMyAdmin.
    • Hosting o contenedor Docker.

    La diferencia es que en PHP trabajaremos con:

    • Clases.
    • Objetos.
    • Atributos.
    • Métodos.
    • Constructores.
    • Encapsulación.
    • Getters y setters.
    • Clases DAO.
    • Separación de responsabilidades.
    • Consultas preparadas.
    • Sesiones.
    • Autoload básico o includes de clases.

    5. Resultado final esperado

    Al finalizar esta versión del proyecto tendremos una aplicación web parecida a la anterior, pero con una organización interna mucho mejor.

    La aplicación incluirá:

    • Página de inicio.
    • Catálogo público de productos.
    • Página de login.
    • Zona administrativa.
    • Alta de productos.
    • Listado administrativo.
    • Edición de productos.
    • Borrado lógico de productos.
    • Subida de imagen por producto.
    • Conexión a base de datos mediante una clase.
    • Entidades representadas mediante clases.
    • Clases DAO para acceder a la base de datos.
    • Uso de sesiones para proteger la administración.
    • Código más limpio y reutilizable.

    Fases del proyecto

    Fase 1: repaso de la versión inicial

    Antes de empezar con la versión orientada a objetos, revisaremos brevemente la versión anterior del proyecto.

    Recordaremos cómo funcionaba:

    • Las páginas públicas.
    • Las páginas administrativas.
    • Los formularios.
    • Los includes.
    • La conexión a la base de datos.
    • Las consultas SELECT, INSERT, UPDATE y DELETE.
    • La subida de imágenes.
    • El login con sesiones.

    Esto es importante porque la versión POO no cambia la finalidad del proyecto. Lo que cambia es la forma de organizar el código.


    Fase 2: análisis de las clases necesarias

    El primer paso será pensar qué elementos importantes tiene nuestro proyecto.

    En una tienda de cuencos tibetanos podemos encontrar estos elementos:

    • Productos.
    • Categorías.
    • Usuarios administradores.
    • Mensajes de contacto.
    • Pedidos.
    • Detalles de pedido.
    • Carrito.
    • Imágenes.

    Cada uno de estos elementos puede representarse con una clase.

    Para empezar, trabajaremos con las clases principales:

    • Producto
    • Categoria
    • Usuario
    • Conexion

    Después añadiremos las clases encargadas de acceder a la base de datos:

    • ProductoDAO
    • CategoriaDAO
    • UsuarioDAO

    Fase 3: estructura de carpetas del proyecto

    En esta versión necesitaremos una estructura más organizada.

    Una posible estructura será esta:

    sonido-interior-poo/
    │
    ├── index.php
    ├── catalogo.php
    ├── login.php
    ├── validar-login.php
    ├── logout.php
    │
    ├── admin/
    │ ├── panel.php
    │ ├── productos.php
    │ ├── producto-alta.php
    │ ├── producto-guardar.php
    │ ├── producto-editar.php
    │ ├── producto-actualizar.php
    │ └── producto-borrar.php
    │
    ├── includes/
    │ ├── header.php
    │ ├── menu.php
    │ ├── menu-admin.php
    │ ├── footer.php
    │ └── seguridad.php
    │
    ├── clases/
    │ ├── Conexion.php
    │ ├── Producto.php
    │ ├── Categoria.php
    │ ├── Usuario.php
    │ ├── ProductoDAO.php
    │ ├── CategoriaDAO.php
    │ └── UsuarioDAO.php
    │
    ├── css/
    │ └── estilos.css
    │
    ├── img/
    │ └── productos/
    │
    └── sql/
    └── tienda_cuencos.sql

    La carpeta más importante de esta versión será clases/.

    Ahí guardaremos las clases del proyecto.


    Fase 4: creación de la clase Conexion

    La primera clase que crearemos será Conexion.

    Esta clase se encargará de conectarse a la base de datos.

    En lugar de tener un archivo conexion.php con variables sueltas, crearemos una clase con un método que devuelva la conexión.

    Ejemplo:

    <?php

    class Conexion {

    private $servidor = "localhost";
    private $usuario = "root";
    private $password = "";
    private $baseDatos = "tienda_cuencos";

    public function conectar() {
    $conexion = new mysqli(
    $this->servidor,
    $this->usuario,
    $this->password,
    $this->baseDatos
    );

    if ($conexion->connect_error) {
    die("Error de conexión: " . $conexion->connect_error);
    }

    $conexion->set_charset("utf8");

    return $conexion;
    }
    }

    ?>

    Con esta clase podremos conectarnos a la base de datos desde cualquier DAO.

    Ejemplo:

    $conexionBD = new Conexion();
    $conexion = $conexionBD->conectar();

    Fase 5: creación de la clase Producto

    Después crearemos la clase Producto.

    Esta clase representará un producto de la tienda.

    Tendrá atributos privados como:

    • ID.
    • Nombre.
    • Descripción.
    • Precio.
    • Stock.
    • Imagen.
    • Diámetro.
    • Peso.
    • Material.
    • Nota musical.
    • Procedencia.
    • Activo.
    • Categoría.

    Ejemplo:

    <?php

    class Producto {

    private $idProducto;
    private $nombre;
    private $descripcion;
    private $precio;
    private $stock;
    private $imagen;
    private $diametro;
    private $peso;
    private $material;
    private $notaMusical;
    private $procedencia;
    private $activo;
    private $idCategoria;

    public function __construct(
    $idProducto = null,
    $nombre = "",
    $descripcion = "",
    $precio = 0,
    $stock = 0,
    $imagen = "",
    $diametro = 0,
    $peso = 0,
    $material = "",
    $notaMusical = "",
    $procedencia = "",
    $activo = true,
    $idCategoria = null
    ) {
    $this->idProducto = $idProducto;
    $this->nombre = $nombre;
    $this->descripcion = $descripcion;
    $this->precio = $precio;
    $this->stock = $stock;
    $this->imagen = $imagen;
    $this->diametro = $diametro;
    $this->peso = $peso;
    $this->material = $material;
    $this->notaMusical = $notaMusical;
    $this->procedencia = $procedencia;
    $this->activo = $activo;
    $this->idCategoria = $idCategoria;
    }

    public function getIdProducto() {
    return $this->idProducto;
    }

    public function getNombre() {
    return $this->nombre;
    }

    public function setNombre($nombre) {
    $this->nombre = $nombre;
    }

    public function getDescripcion() {
    return $this->descripcion;
    }

    public function setDescripcion($descripcion) {
    $this->descripcion = $descripcion;
    }

    public function getPrecio() {
    return $this->precio;
    }

    public function setPrecio($precio) {
    $this->precio = $precio;
    }

    public function getStock() {
    return $this->stock;
    }

    public function setStock($stock) {
    $this->stock = $stock;
    }
    }

    ?>

    Durante el proyecto iremos completando la clase con todos los getters y setters necesarios.


    Fase 6: creación de la clase Categoria

    La clase Categoria representará una categoría de producto.

    Ejemplo:

    <?php

    class Categoria {

    private $idCategoria;
    private $nombre;
    private $descripcion;
    private $activo;

    public function __construct(
    $idCategoria = null,
    $nombre = "",
    $descripcion = "",
    $activo = true
    ) {
    $this->idCategoria = $idCategoria;
    $this->nombre = $nombre;
    $this->descripcion = $descripcion;
    $this->activo = $activo;
    }

    public function getIdCategoria() {
    return $this->idCategoria;
    }

    public function getNombre() {
    return $this->nombre;
    }

    public function setNombre($nombre) {
    $this->nombre = $nombre;
    }

    public function getDescripcion() {
    return $this->descripcion;
    }

    public function setDescripcion($descripcion) {
    $this->descripcion = $descripcion;
    }

    public function getActivo() {
    return $this->activo;
    }

    public function setActivo($activo) {
    $this->activo = $activo;
    }
    }

    ?>

    Esta clase nos permitirá trabajar con categorías de forma ordenada.


    Fase 7: creación de la clase Usuario

    La clase Usuario representará a los usuarios administradores.

    Tendrá atributos como:

    • ID.
    • Nombre.
    • Email.
    • Usuario.
    • Password.
    • Rol.

    Ejemplo:

    <?php

    class Usuario {

    private $idUsuario;
    private $nombre;
    private $email;
    private $usuario;
    private $password;
    private $rol;

    public function __construct(
    $idUsuario = null,
    $nombre = "",
    $email = "",
    $usuario = "",
    $password = "",
    $rol = "admin"
    ) {
    $this->idUsuario = $idUsuario;
    $this->nombre = $nombre;
    $this->email = $email;
    $this->usuario = $usuario;
    $this->password = $password;
    $this->rol = $rol;
    }

    public function getIdUsuario() {
    return $this->idUsuario;
    }

    public function getNombre() {
    return $this->nombre;
    }

    public function getUsuario() {
    return $this->usuario;
    }

    public function getPassword() {
    return $this->password;
    }

    public function getRol() {
    return $this->rol;
    }
    }

    ?>

    Esta clase se usará principalmente para el login y la gestión de sesiones.


    Fase 8: qué es una clase DAO

    En esta versión del proyecto usaremos clases DAO.

    DAO significa Data Access Object, es decir, objeto de acceso a datos.

    Una clase DAO se encarga de hablar con la base de datos.

    Por ejemplo, la clase Producto representa los datos de un producto, pero no debería ser la encargada de hacer consultas SQL.

    Para eso tendremos ProductoDAO.

    La clase ProductoDAO tendrá métodos como:

    • obtenerTodos()
    • obtenerPorId($id)
    • crear($producto)
    • actualizar($producto)
    • eliminar($id)
    • disminuirStock($idProducto, $cantidad)

    La ventaja es que las consultas SQL quedan agrupadas en una clase concreta.


    Fase 9: creación de ProductoDAO

    La clase ProductoDAO será una de las más importantes del proyecto.

    Ejemplo inicial:

    <?php

    require_once "Conexion.php";
    require_once "Producto.php";

    class ProductoDAO {

    private $conexion;

    public function __construct() {
    $conexionBD = new Conexion();
    $this->conexion = $conexionBD->conectar();
    }

    public function obtenerTodos() {
    $sql = "SELECT * FROM productos WHERE activo = 1";
    $resultado = $this->conexion->query($sql);

    $productos = [];

    while ($fila = $resultado->fetch_assoc()) {
    $producto = new Producto(
    $fila["id_producto"],
    $fila["nombre"],
    $fila["descripcion"],
    $fila["precio"],
    $fila["stock"],
    $fila["imagen"],
    $fila["diametro"],
    $fila["peso"],
    $fila["material"],
    $fila["nota_musical"],
    $fila["procedencia"],
    $fila["activo"],
    $fila["id_categoria"]
    );

    $productos[] = $producto;
    }

    return $productos;
    }
    }

    ?>

    Ahora, desde catalogo.php, podremos obtener los productos así:

    require_once "clases/ProductoDAO.php";

    $productoDAO = new ProductoDAO();
    $productos = $productoDAO->obtenerTodos();

    Y después recorrerlos:

    foreach ($productos as $producto) {
    echo "<h3>" . $producto->getNombre() . "</h3>";
    echo "<p>" . $producto->getPrecio() . " €</p>";
    }

    Fase 10: mostrar el catálogo usando objetos

    En la página catalogo.php, ya no haremos directamente una consulta SQL.

    La página simplemente pedirá los productos a ProductoDAO.

    Ejemplo:

    <?php
    require_once "clases/ProductoDAO.php";
    include("includes/header.php");
    include("includes/menu.php");

    $productoDAO = new ProductoDAO();
    $productos = $productoDAO->obtenerTodos();
    ?>

    <main class="contenedor">
    <h1>Catálogo de productos</h1>

    <section class="grid-productos">
    <?php foreach ($productos as $producto): ?>
    <article class="tarjeta-producto">
    <img src="img/productos/<?php echo $producto->getImagen(); ?>" alt="<?php echo $producto->getNombre(); ?>">
    <h3><?php echo $producto->getNombre(); ?></h3>
    <p><?php echo $producto->getPrecio(); ?> €</p>
    </article>
    <?php endforeach; ?>
    </section>
    </main>

    <?php include("includes/footer.php"); ?>

    Para que esto funcione, la clase Producto deberá tener métodos como:

    • getImagen()
    • getNombre()
    • getPrecio()

    Fase 11: alta de productos usando objetos

    Cuando enviemos el formulario de alta, recogeremos los datos del formulario y crearemos un objeto Producto.

    Ejemplo en producto-guardar.php:

    require_once "../clases/Producto.php";
    require_once "../clases/ProductoDAO.php";

    $producto = new Producto();

    $producto->setNombre($_POST["nombre"]);
    $producto->setDescripcion($_POST["descripcion"]);
    $producto->setPrecio($_POST["precio"]);
    $producto->setStock($_POST["stock"]);
    $producto->setMaterial($_POST["material"]);
    $producto->setProcedencia($_POST["procedencia"]);

    $productoDAO = new ProductoDAO();
    $productoDAO->crear($producto);

    Después, dentro de ProductoDAO, tendremos el método crear().

    Ejemplo:

    public function crear($producto) {
    $sql = "INSERT INTO productos
    (nombre, descripcion, precio, stock, material, procedencia)
    VALUES (?, ?, ?, ?, ?, ?)";

    $stmt = $this->conexion->prepare($sql);

    $nombre = $producto->getNombre();
    $descripcion = $producto->getDescripcion();
    $precio = $producto->getPrecio();
    $stock = $producto->getStock();
    $material = $producto->getMaterial();
    $procedencia = $producto->getProcedencia();

    $stmt->bind_param(
    "ssdiss",
    $nombre,
    $descripcion,
    $precio,
    $stock,
    $material,
    $procedencia
    );

    return $stmt->execute();
    }

    Este enfoque es más limpio porque el archivo del formulario no contiene directamente toda la consulta SQL.


    Fase 12: listado administrativo usando objetos

    El listado administrativo también usará ProductoDAO.

    La página admin/productos.php pedirá todos los productos:

    $productoDAO = new ProductoDAO();
    $productos = $productoDAO->obtenerTodos();

    Después los mostrará en una tabla:

    <?php foreach ($productos as $producto): ?>
    <tr>
    <td><?php echo $producto->getIdProducto(); ?></td>
    <td><?php echo $producto->getNombre(); ?></td>
    <td><?php echo $producto->getPrecio(); ?> €</td>
    <td><?php echo $producto->getStock(); ?></td>
    <td>
    <a href="producto-editar.php?id=<?php echo $producto->getIdProducto(); ?>">Editar</a>
    <a href="producto-borrar.php?id=<?php echo $producto->getIdProducto(); ?>">Borrar</a>
    </td>
    </tr>
    <?php endforeach; ?>

    La página se centra en mostrar información, no en saber cómo se consulta la base de datos.


    Fase 13: obtener un producto por ID

    Para editar un producto necesitaremos recuperarlo por su ID.

    Añadiremos este método a ProductoDAO:

    public function obtenerPorId($id) {
    $sql = "SELECT * FROM productos WHERE id_producto = ?";
    $stmt = $this->conexion->prepare($sql);
    $stmt->bind_param("i", $id);
    $stmt->execute();

    $resultado = $stmt->get_result();

    if ($fila = $resultado->fetch_assoc()) {
    return new Producto(
    $fila["id_producto"],
    $fila["nombre"],
    $fila["descripcion"],
    $fila["precio"],
    $fila["stock"],
    $fila["imagen"],
    $fila["diametro"],
    $fila["peso"],
    $fila["material"],
    $fila["nota_musical"],
    $fila["procedencia"],
    $fila["activo"],
    $fila["id_categoria"]
    );
    }

    return null;
    }

    Después, desde producto-editar.php:

    $id = $_GET["id"];

    $productoDAO = new ProductoDAO();
    $producto = $productoDAO->obtenerPorId($id);

    Así podremos rellenar el formulario de edición con los datos actuales del producto.


    Fase 14: actualización de productos

    Cuando se envíe el formulario de edición, crearemos un objeto Producto con los datos actualizados.

    Después llamaremos al método actualizar() de ProductoDAO.

    Ejemplo:

    $producto = new Producto();

    $producto->setIdProducto($_POST["id_producto"]);
    $producto->setNombre($_POST["nombre"]);
    $producto->setDescripcion($_POST["descripcion"]);
    $producto->setPrecio($_POST["precio"]);
    $producto->setStock($_POST["stock"]);

    $productoDAO = new ProductoDAO();
    $productoDAO->actualizar($producto);

    El método actualizar() hará una consulta UPDATE.

    public function actualizar($producto) {
    $sql = "UPDATE productos
    SET nombre = ?, descripcion = ?, precio = ?, stock = ?
    WHERE id_producto = ?";

    $stmt = $this->conexion->prepare($sql);

    $nombre = $producto->getNombre();
    $descripcion = $producto->getDescripcion();
    $precio = $producto->getPrecio();
    $stock = $producto->getStock();
    $id = $producto->getIdProducto();

    $stmt->bind_param("ssdii", $nombre, $descripcion, $precio, $stock, $id);

    return $stmt->execute();
    }

    Fase 15: borrado lógico de productos

    En lugar de borrar físicamente un producto, lo marcaremos como inactivo.

    En ProductoDAO añadiremos un método eliminar():

    public function eliminar($id) {
    $sql = "UPDATE productos SET activo = 0 WHERE id_producto = ?";
    $stmt = $this->conexion->prepare($sql);
    $stmt->bind_param("i", $id);

    return $stmt->execute();
    }

    Desde producto-borrar.php:

    $id = $_GET["id"];

    $productoDAO = new ProductoDAO();
    $productoDAO->eliminar($id);

    header("Location: productos.php");
    exit();

    Con esto el producto seguirá en la base de datos, pero dejará de mostrarse en la tienda.


    Fase 16: gestión de categorías con CategoriaDAO

    Igual que tenemos ProductoDAO, crearemos CategoriaDAO.

    Esta clase tendrá métodos como:

    • obtenerTodas()
    • obtenerPorId($id)
    • crear($categoria)
    • actualizar($categoria)
    • eliminar($id)

    Ejemplo básico:

    <?php

    require_once "Conexion.php";
    require_once "Categoria.php";

    class CategoriaDAO {

    private $conexion;

    public function __construct() {
    $conexionBD = new Conexion();
    $this->conexion = $conexionBD->conectar();
    }

    public function obtenerTodas() {
    $sql = "SELECT * FROM categorias WHERE activo = 1";
    $resultado = $this->conexion->query($sql);

    $categorias = [];

    while ($fila = $resultado->fetch_assoc()) {
    $categoria = new Categoria(
    $fila["id_categoria"],
    $fila["nombre"],
    $fila["descripcion"],
    $fila["activo"]
    );

    $categorias[] = $categoria;
    }

    return $categorias;
    }
    }

    ?>

    Esto nos permitirá cargar categorías dinámicamente en el formulario de alta de productos.


    Fase 17: login usando UsuarioDAO

    Para el login crearemos la clase UsuarioDAO.

    Esta clase tendrá un método para buscar un usuario por su nombre de usuario o email.

    Ejemplo:

    public function obtenerPorUsuario($usuario) {
    $sql = "SELECT * FROM usuarios WHERE usuario = ? OR email = ?";
    $stmt = $this->conexion->prepare($sql);
    $stmt->bind_param("ss", $usuario, $usuario);
    $stmt->execute();

    $resultado = $stmt->get_result();

    if ($fila = $resultado->fetch_assoc()) {
    return new Usuario(
    $fila["id_usuario"],
    $fila["nombre"],
    $fila["email"],
    $fila["usuario"],
    $fila["password"],
    $fila["rol"]
    );
    }

    return null;
    }

    Después, en validar-login.php:

    session_start();

    require_once "clases/UsuarioDAO.php";

    $usuarioFormulario = $_POST["usuario"];
    $passwordFormulario = $_POST["password"];

    $usuarioDAO = new UsuarioDAO();
    $usuario = $usuarioDAO->obtenerPorUsuario($usuarioFormulario);

    if ($usuario != null && password_verify($passwordFormulario, $usuario->getPassword())) {
    $_SESSION["usuario"] = $usuario->getUsuario();
    $_SESSION["rol"] = $usuario->getRol();

    header("Location: admin/panel.php");
    exit();
    } else {
    header("Location: login.php?error=1");
    exit();
    }

    Así el login queda mucho más ordenado.


    Fase 18: protección de páginas privadas

    Seguiremos usando sesiones para proteger la parte administrativa.

    El archivo includes/seguridad.php puede mantenerse parecido a la versión anterior.

    <?php

    session_start();

    if (!isset($_SESSION["usuario"])) {
    header("Location: ../login.php");
    exit();
    }

    ?>

    En cada página privada incluiremos este archivo.

    <?php include("../includes/seguridad.php"); ?>

    Fase 19: subida de imágenes usando una función auxiliar

    La subida de imágenes puede hacerse al principio dentro de producto-guardar.php, pero podemos mejorarla creando una función o una clase auxiliar.

    Una opción sencilla sería crear:

    clases/GestorImagenes.php

    Ejemplo:

    <?php

    class GestorImagenes {

    public static function subirImagen($archivo, $carpetaDestino) {
    $nombreImagen = time() . "_" . basename($archivo["name"]);
    $rutaDestino = $carpetaDestino . $nombreImagen;

    if (move_uploaded_file($archivo["tmp_name"], $rutaDestino)) {
    return $nombreImagen;
    }

    return null;
    }
    }

    ?>

    Después, en producto-guardar.php:

    require_once "../clases/GestorImagenes.php";

    $imagen = GestorImagenes::subirImagen(
    $_FILES["imagen"],
    "../img/productos/"
    );

    $producto->setImagen($imagen);

    Esto permite separar la lógica de subida de archivos del resto del código.


    Fase 20: autoload básico de clases

    Cuando el proyecto crece, puede resultar pesado escribir muchos require_once.

    Por ejemplo:

    require_once "clases/Conexion.php";
    require_once "clases/Producto.php";
    require_once "clases/ProductoDAO.php";
    require_once "clases/Categoria.php";
    require_once "clases/CategoriaDAO.php";

    Para evitarlo, podemos crear un pequeño autoload.

    Ejemplo en includes/autoload.php:

    <?php

    spl_autoload_register(function ($nombreClase) {
    require_once __DIR__ . "/../clases/" . $nombreClase . ".php";
    });

    ?>

    Después, en cada página solo haríamos:

    require_once "includes/autoload.php";

    O desde la carpeta admin:

    require_once "../includes/autoload.php";

    Esto nos permitirá cargar clases automáticamente cuando las necesitemos.


    Fase 21: diagrama de clases

    En esta versión será especialmente importante trabajar con un diagrama de clases.

    El diagrama nos ayudará a entender qué clases existen y cómo se relacionan.

    Algunas clases principales serán:

    • Conexion
    • Producto
    • Categoria
    • Usuario
    • ProductoDAO
    • CategoriaDAO
    • UsuarioDAO
    • GestorImagenes

    La relación sería sencilla:

    • ProductoDAO usa Conexion.
    • ProductoDAO crea y devuelve objetos Producto.
    • CategoriaDAO usa Conexion.
    • CategoriaDAO crea y devuelve objetos Categoria.
    • UsuarioDAO usa Conexion.
    • UsuarioDAO crea y devuelve objetos Usuario.
    • Las páginas PHP usan los DAO para obtener o guardar datos.

    Este diagrama nos permitirá ver que las páginas ya no hablan directamente con la base de datos, sino que lo hacen a través de clases especializadas.


    Fase 22: diagrama de base de datos

    El diagrama de base de datos seguirá siendo parecido al de la versión anterior.

    Tendremos tablas como:

    • usuarios
    • categorias
    • productos
    • mensajes
    • pedidos
    • detalle_pedido
    • carrito
    • carrito_producto

    La tabla más importante al principio será productos, relacionada con categorias.

    La diferencia es que ahora intentaremos que las tablas tengan una correspondencia clara con las clases del proyecto.

    Por ejemplo:

    • Tabla productos → Clase Producto
    • Tabla categorias → Clase Categoria
    • Tabla usuarios → Clase Usuario

    Esto ayuda a entender la relación entre el modelo de datos y el modelo de objetos.


    Fase 23: preparación para hosting

    El despliegue en hosting será similar al de la versión anterior.

    Tendremos que subir:

    • Archivos PHP.
    • Carpeta clases/.
    • Carpeta includes/.
    • Carpeta css/.
    • Carpeta img/.
    • Base de datos exportada.

    También deberemos modificar los datos de conexión dentro de la clase Conexion.

    En local podríamos tener:

    private $servidor = "localhost";
    private $usuario = "root";
    private $password = "";
    private $baseDatos = "tienda_cuencos";

    En hosting tendremos otros datos:

    private $servidor = "servidor_del_hosting";
    private $usuario = "usuario_hosting";
    private $password = "password_hosting";
    private $baseDatos = "base_datos_hosting";

    Esta parte nos ayudará a entender que una aplicación debe adaptarse al entorno donde se ejecuta.


    Fase 24: ejecución en Docker

    También podremos preparar el proyecto para ejecutarlo en Docker.

    La diferencia principal será que la clase Conexion deberá conectarse al servicio de base de datos usando el nombre del contenedor.

    Por ejemplo, si en docker-compose.yml el servicio de base de datos se llama db, entonces en PHP usaremos:

    private $servidor = "db";

    Ejemplo de docker-compose.yml:

    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 configuración podríamos acceder a la web desde:

    http://localhost:8080

    Y a phpMyAdmin desde:

    http://localhost:8081

    Fase 25: documentación final del proyecto

    Al terminar esta versión, cada alumno deberá documentar el proyecto.

    La documentación debería incluir:

    • Explicación general del proyecto.
    • Diferencias entre la versión básica y la versión POO.
    • Estructura de carpetas.
    • Diagrama de clases.
    • Diagrama de base de datos.
    • Explicación de las clases principales.
    • Explicación de las clases DAO.
    • Explicación del CRUD.
    • Capturas de pantalla.
    • Problemas encontrados.
    • Mejoras posibles.
    • Conclusión personal.

    En esta versión será especialmente importante que el alumno sepa explicar por qué se han creado ciertas clases y qué responsabilidad tiene cada una.


    26. Qué aprenderemos con esta versión

    Con esta versión aprenderemos a organizar mejor un proyecto PHP.

    No solo veremos cómo hacer que una aplicación funcione, sino cómo estructurarla para que sea más clara y mantenible.

    Aprenderemos conceptos como:

    • Clases.
    • Objetos.
    • Atributos.
    • Métodos.
    • Constructores.
    • Getters y setters.
    • Encapsulación.
    • DAO.
    • Separación de responsabilidades.
    • Consultas preparadas.
    • Sesiones.
    • Subida de archivos.
    • Reutilización de código.
    • Relación entre tablas y clases.
    • Preparación del proyecto para hosting o Docker.

    Esta versión es un paso intermedio muy importante antes de trabajar con arquitecturas más avanzadas como MVC o frameworks como Laravel.


    27. Conclusión

    La versión orientada a objetos de Sonido Interior nos permitirá mejorar el mismo proyecto que ya conocemos.

    En lugar de empezar una aplicación totalmente nueva, evolucionaremos una tienda sencilla construida con PHP básico hacia una estructura más ordenada y profesional.

    Esto nos permitirá entender mejor por qué existe la programación orientada a objetos y qué problemas resuelve.

    La idea principal es que el alumno vea una evolución clara:

    Primero hacemos que funcione.

    Después hacemos que esté mejor organizado.

    Y finalmente preparamos el proyecto para poder crecer, mantenerse y desplegarse en un entorno real.

  • Proyecto web en PHP: tienda de cuencos tibetanos

    Proyecto web en PHP: tienda de cuencos tibetanos

    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.html
    • catalogo.html
    • login.html
    • admin-alta-producto.html
    • admin-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.html por index.php
    • catalogo.html por catalogo.php
    • login.html por login.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.php
    • menu.php
    • menu-admin.php
    • footer.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:

    • usuarios
    • categorias
    • productos
    • mensajes
    • pedidos
    • detalle_pedido
    • carrito
    • carrito_producto

    Para empezar, nos centraremos sobre todo en las tablas más importantes:

    • usuarios
    • categorias
    • productos

    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á:

    1. El usuario selecciona una imagen.
    2. El formulario envía el archivo al servidor.
    3. PHP recibe el archivo temporal.
    4. PHP mueve el archivo a img/productos/.
    5. 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á:

    1. Entrar en phpMyAdmin.
    2. Seleccionar la base de datos.
    3. Ir a la opción exportar.
    4. Guardar el archivo .sql.

    Después, en el hosting:

    1. Crear una nueva base de datos.
    2. Entrar en phpMyAdmin del hosting.
    3. Importar el archivo .sql.
    4. 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.

  • Proyecto Mundo Oficios: diseño y desarrollo de una tienda online de muñecos por profesiones

    Proyecto Mundo Oficios: diseño y desarrollo de una tienda online de muñecos por profesiones

    Introducción

    En este proyecto vamos a diseñar, analizar y desarrollar una aplicación web completa basada en una tienda online ficticia llamada Mundo Oficios.

    La idea principal de la aplicación es crear una tienda de muñecos de estilo coleccionable, inspirados en diferentes profesiones: bomberos, doctoras, astronautas, chefs, policías, profesoras, constructores y muchas otras figuras similares.

    El objetivo no es únicamente crear una página bonita, sino recorrer varias fases reales del desarrollo de una aplicación web: desde la idea inicial y el diseño visual, hasta el análisis de clases, la base de datos, los casos de uso y la futura implementación en Java.

    Este proyecto nos servirá para practicar conceptos fundamentales del desarrollo de aplicaciones web, combinando diseño, programación, bases de datos y organización de un proyecto.


    1. Objetivo general del proyecto

    El objetivo de Mundo Oficios es construir una aplicación web que permita mostrar y gestionar productos de una tienda online.

    La aplicación tendrá dos partes principales:

    Parte pública

    Será la zona visible para cualquier usuario que visite la web. En esta parte se mostrarán los productos, las categorías, los packs, la información corporativa y las llamadas a la acción para consultar o comprar productos.

    La parte pública representa lo que vería un cliente normal al entrar en la tienda.

    Parte privada o panel de administración

    Será la zona interna de la aplicación. Solo podrán acceder usuarios autorizados, como administradores o gestores de la tienda.

    Desde esta zona privada se podrán dar de alta productos, modificar información, gestionar categorías, subir imágenes, controlar stock, revisar pedidos y consultar datos importantes de la tienda.


    2. Qué vamos a trabajar con este proyecto

    Este proyecto está pensado para trabajar varias competencias al mismo tiempo.

    Durante el desarrollo de Mundo Oficios vamos a practicar:

    • Diseño de interfaces con Figma.
    • Creación de prototipos de páginas web.
    • Organización visual de una web pública.
    • Diseño de una zona privada de administración.
    • Análisis de requisitos.
    • Diagrama de casos de uso.
    • Diagrama de clases.
    • Diagrama entidad-relación de base de datos.
    • Modelado de clases Java.
    • Diseño de tablas SQL.
    • Relación entre frontend, backend y base de datos.
    • Preparación de formularios web.
    • Gestión de productos.
    • Organización de imágenes, categorías y etiquetas.
    • Conceptos básicos de una tienda online.

    La intención es que el alumno no vea cada parte como algo aislado, sino como piezas de un mismo proyecto.

    Una aplicación real no se construye solo escribiendo código. Antes de programar hay que pensar qué necesita el usuario, cómo se va a organizar la información, qué pantallas va a tener la aplicación, qué datos se van a guardar y qué clases representarán esos datos dentro del programa.


    3. Descripción de la aplicación

    Mundo Oficios será una tienda online ficticia especializada en muñecos de diferentes profesiones.

    Cada producto representará una figura concreta. Por ejemplo:

    • Leo Bombero.
    • Nora Doctora.
    • Max Astronauta.
    • Sofía Chef.
    • Policía urbano.
    • Profesora de primaria.
    • Constructor.
    • Mecánica.
    • Científica.
    • Piloto.
    • Enfermero.

    Cada muñeco tendrá una ficha de producto con información básica:

    • Nombre del producto.
    • Profesión.
    • Categoría.
    • Precio.
    • Precio en oferta, si existe.
    • Stock disponible.
    • Edad recomendada.
    • Descripción corta.
    • Descripción completa.
    • Imágenes del producto.
    • Etiquetas.
    • Estado de publicación.
    • Indicación de si está visible o no en la tienda.

    La tienda estará organizada por categorías. Por ejemplo:

    • Emergencias.
    • Salud.
    • Educación.
    • Espacio.
    • Construcción.
    • Cocina.

    Esto nos permite trabajar una estructura típica de comercio electrónico, pero con una temática sencilla, visual y fácil de entender.


    4. Diseño de la página de inicio pública

    La primera parte del proyecto será el diseño de la home o página de inicio.

    La home es una de las páginas más importantes de una web, porque suele ser la primera pantalla que ve el usuario al entrar. Debe explicar de forma rápida qué ofrece la tienda, transmitir confianza y guiar al visitante hacia las secciones principales.

    En nuestro caso, la home de Mundo Oficios tendrá un diseño corporativo, limpio y moderno.

    Elementos principales de la home

    La página de inicio incluirá:

    Cabecera

    La cabecera contendrá el logotipo de Mundo Oficios, un menú de navegación y algunos iconos básicos.

    El menú puede incluir opciones como:

    • Inicio.
    • Profesiones.
    • Categorías.
    • Packs.
    • Sobre nosotros.
    • Contacto.

    También aparecerán iconos de búsqueda, usuario y carrito.

    La cabecera debe ser clara, sencilla y fácil de reconocer. En una web real, el usuario debe poder encontrar rápidamente las secciones importantes.

    Hero principal

    El hero es la sección principal que aparece al inicio de la página.

    En este proyecto, el hero tendrá una frase destacada como:

    Figuras articuladas que inspiran futuros

    Debajo se puede incluir un texto breve explicando la propuesta de la tienda:

    Descubre muñecos de profesiones diseñados para imaginar, jugar y aprender sin límites.

    También aparecerán botones de acción, por ejemplo:

    • Ver catálogo.
    • Conoce nuestra historia.

    El hero debe combinar texto, botones e imagen. En este caso, la imagen principal será un conjunto de muñecos representando varias profesiones.

    Sección Nuestra propuesta

    Esta sección explicará el valor de la marca.

    Puede incluir tres bloques:

    • Calidad que se siente.
    • Colecciona y combina.
    • Aprende jugando.

    Esta parte es importante porque no todo en una tienda online debe ser producto y precio. También hay que transmitir una idea de marca.

    Categorías

    La sección de categorías permitirá al usuario entrar en grupos de productos.

    Por ejemplo:

    • Emergencias.
    • Salud.
    • Espacio.
    • Construcción.

    Cada categoría puede representarse con una tarjeta sencilla, un icono y un enlace para acceder a ella.

    Productos destacados

    En lugar de mostrar muchos productos, la versión más corporativa de la home mostrará pocos productos destacados.

    Esto ayuda a que el diseño sea más limpio y elegante.

    Por ejemplo, podemos mostrar solo dos productos:

    • Leo Bombero.
    • Nora Doctora.

    Cada tarjeta de producto puede incluir:

    • Imagen.
    • Nombre.
    • Categoría.
    • Precio.
    • Valoración.
    • Botón de añadir al carrito.

    La home también puede incluir un banner para packs o colecciones.

    Por ejemplo:

    Packs y colecciones para cada aventura

    Esta sección puede servir para promocionar productos agrupados o descuentos especiales.

    Sección de confianza

    Una tienda online necesita transmitir seguridad.

    Por eso incluiremos una sección con elementos como:

    • Seguridad ante todo.
    • Diseño pensado para niños.
    • Envíos rápidos y seguros.
    • Atención cercana.

    Estos bloques ayudan a reforzar la confianza del usuario antes de comprar.

    Newsletter o llamada a la acción

    Al final de la página puede incluirse una sección para que el usuario deje su correo electrónico y reciba novedades u ofertas.

    Por ejemplo:

    Inspírate con novedades y ofertas exclusivas

    Esta parte nos permite practicar formularios simples dentro del diseño.

    El footer cerrará la página con enlaces secundarios, redes sociales, métodos de pago y datos básicos de la tienda.


    5. Diseño de la parte privada

    Además de la web pública, el proyecto tendrá una parte privada.

    La parte privada es el panel de administración de la tienda. No está pensada para clientes, sino para las personas que gestionan el contenido y los productos.

    En una aplicación real, este panel estaría protegido mediante usuario y contraseña.

    Página de login

    Antes de entrar al panel, el administrador deberá iniciar sesión.

    La pantalla de login tendrá un diseño corporativo y limpio, con dos zonas principales:

    Zona visual de marca

    En una parte de la pantalla aparecerá una imagen corporativa, con varios muñecos y un mensaje relacionado con la gestión de la tienda.

    Por ejemplo:

    Gestiona tu tienda de profesiones desde un solo lugar

    Esta zona ayuda a reforzar la identidad visual del proyecto.

    Formulario de acceso

    En la otra parte de la pantalla aparecerá el formulario de login.

    Tendrá los siguientes campos:

    • Correo electrónico.
    • Contraseña.
    • Checkbox de recordarme.
    • Enlace para recuperar contraseña.
    • Botón de iniciar sesión.
    • Opción secundaria de acceso con Google.
    • Texto de ayuda o soporte.

    Aunque en una primera fase no implementemos todas estas funcionalidades, sí es interesante diseñarlas para entender cómo sería una aplicación real.


    6. Alta de productos en la parte privada

    Una de las pantallas más importantes del panel privado será la de alta de producto.

    Esta pantalla permitirá al administrador crear una nueva ficha de producto para la tienda.

    Estructura general

    La pantalla tendrá:

    • Menú lateral.
    • Barra superior.
    • Zona principal de formulario.
    • Paneles auxiliares a la derecha.

    El menú lateral permitirá acceder a las diferentes secciones del panel.

    Puede incluir opciones como:

    • Resumen.
    • Productos.
    • Categorías.
    • Pedidos.
    • Clientes.
    • Promociones.
    • Estadísticas.
    • Ajustes.

    La opción Productos aparecerá destacada, porque estaremos dentro de esa sección.

    Barra superior

    La barra superior puede incluir:

    • Campo de búsqueda.
    • Icono de notificaciones.
    • Perfil del administrador.

    Estos elementos son habituales en paneles de administración modernos.

    Formulario de alta

    La parte central de la pantalla contendrá el formulario para crear un producto.

    Los campos principales serán:

    • Nombre del producto.
    • SKU.
    • Precio.
    • Precio oferta.
    • Categoría.
    • Profesión.
    • Stock.
    • Edad recomendada.
    • Descripción corta.
    • Descripción completa.
    • Etiquetas.
    • Producto destacado.
    • Visible en tienda.
    • Estado del producto.

    Este formulario nos permitirá trabajar muchos tipos de controles:

    • Inputs de texto.
    • Inputs numéricos.
    • Selectores desplegables.
    • Textareas.
    • Switches.
    • Radios.
    • Botones.
    • Zona de subida de imágenes.

    Galería de imágenes

    Cada producto podrá tener varias imágenes.

    Por ejemplo:

    • Imagen frontal.
    • Imagen lateral.
    • Imagen trasera.
    • Imagen de detalle.

    En el diseño aparecerá una sección de galería donde se podrán subir imágenes del producto.

    En una aplicación real, estas imágenes se guardarían en el servidor o en un servicio de almacenamiento, y en la base de datos se guardaría la ruta o URL de cada imagen.

    Panel de vista previa

    A la derecha del formulario puede aparecer una vista previa del producto.

    Esta vista previa permite comprobar cómo se verá el producto antes de publicarlo.

    Puede mostrar:

    • Imagen principal.
    • Nombre.
    • Categoría.
    • Precio.
    • Precio de oferta.
    • Stock.
    • SKU.

    Este tipo de panel ayuda mucho en aplicaciones de administración, porque permite validar la información antes de guardarla.

    Panel de organización

    También puede haber un bloque para información interna:

    • Colección.
    • Proveedor.
    • Clase de envío.
    • Notas internas.

    Esto no siempre será visible para el cliente, pero sí puede ser útil para la gestión interna de la tienda.

    Botones finales

    Al final del formulario tendremos dos acciones principales:

    • Guardar borrador.
    • Publicar producto.

    Esto nos permite explicar la diferencia entre un producto que está guardado pero no publicado y un producto que ya aparece en la tienda pública.


    7. Diagrama de casos de uso

    El diagrama de casos de uso nos ayuda a entender qué puede hacer cada tipo de usuario dentro del sistema.

    En este proyecto tenemos varios actores:

    Visitante

    Es una persona que entra en la web sin estar registrada.

    Puede:

    • Ver la página de inicio.
    • Ver el catálogo.
    • Filtrar productos.
    • Ver fichas de producto.
    • Registrarse o iniciar sesión.

    Cliente

    Es un usuario que puede comprar o consultar sus pedidos.

    Puede:

    • Ver productos.
    • Añadir productos al carrito.
    • Realizar pedidos.
    • Pagar pedidos.
    • Consultar sus pedidos.

    Administrador o gestor

    Es el usuario que accede a la parte privada.

    Puede:

    • Acceder al panel privado.
    • Gestionar productos.
    • Dar de alta productos.
    • Editar productos.
    • Eliminar o desactivar productos.
    • Subir imágenes.
    • Gestionar categorías.
    • Gestionar profesiones.
    • Gestionar pedidos.
    • Gestionar promociones.
    • Consultar estadísticas.
    • Gestionar usuarios.

    Pasarela de pago

    Es un sistema externo que interviene cuando el cliente paga un pedido.

    En una aplicación real, podría ser PayPal, Stripe, Redsys u otra plataforma similar.

    El diagrama de casos de uso nos sirve para ver el sistema desde el punto de vista funcional. No se centra en las clases ni en la base de datos, sino en las acciones que los usuarios pueden realizar.


    8. Diagrama de clases

    El diagrama de clases representa la estructura del sistema desde el punto de vista de la programación orientada a objetos.

    En Java, cada clase representará un concepto importante del proyecto.

    Clase Producto

    La clase Producto es una de las más importantes.

    Representa cada muñeco que se vende en la tienda.

    Puede tener atributos como:

    • id.
    • nombre.
    • sku.
    • precio.
    • precioOferta.
    • stock.
    • descripcionCorta.
    • descripcionCompleta.
    • edadRecomendada.
    • destacado.
    • visible.
    • estado.

    También puede tener métodos como:

    • publicar.
    • guardarBorrador.
    • aplicarOferta.
    • quitarOferta.
    • actualizarStock.
    • estaDisponible.

    Esta clase estará relacionada con otras clases como Categoria, Profesion, ImagenProducto, Etiqueta, Coleccion y Proveedor.

    Clase Categoria

    La clase Categoria sirve para agrupar productos.

    Por ejemplo:

    • Emergencias.
    • Salud.
    • Educación.
    • Espacio.
    • Construcción.
    • Cocina.

    Una categoría puede tener muchos productos.

    Clase Profesion

    La clase Profesion representa la profesión concreta del muñeco.

    Por ejemplo:

    • Bombero.
    • Doctora.
    • Astronauta.
    • Chef.
    • Policía.
    • Profesora.

    Es importante diferenciar categoría y profesión.

    Por ejemplo, un producto puede estar en la categoría Emergencias y tener la profesión Bombero.

    Clase ImagenProducto

    Un producto puede tener varias imágenes.

    Por eso existe la clase ImagenProducto.

    Esta clase puede guardar:

    • URL de la imagen.
    • Texto alternativo.
    • Si es imagen principal.
    • Orden de aparición.

    Esto permite que un mismo producto tenga una galería de imágenes.

    Clase Etiqueta

    Las etiquetas permiten clasificar productos de forma más flexible.

    Por ejemplo:

    • bombero.
    • emergencias.
    • regalo.
    • colección.
    • oferta.
    • niños.

    Un producto puede tener muchas etiquetas y una etiqueta puede estar asociada a muchos productos.

    Por eso esta relación suele convertirse en una tabla intermedia en la base de datos.

    Clase Cliente

    La clase Cliente representa a una persona que compra en la tienda.

    Puede tener:

    • nombre.
    • apellidos.
    • email.
    • teléfono.

    Un cliente puede tener varias direcciones y varios pedidos.

    Clase Pedido

    La clase Pedido representa una compra realizada por un cliente.

    Puede tener:

    • fecha.
    • estado.
    • subtotal.
    • gastos de envío.
    • total.

    Un pedido estará formado por varias líneas de pedido.

    Clase LineaPedido

    La clase LineaPedido representa cada producto concreto dentro de un pedido.

    Por ejemplo, si un cliente compra dos muñecos de bombero y uno de astronauta, el pedido tendrá dos líneas:

    • Línea 1: Leo Bombero, cantidad 2.
    • Línea 2: Max Astronauta, cantidad 1.

    Cada línea tiene su cantidad, precio unitario y subtotal.

    Clase Pago

    La clase Pago representa la información relacionada con el pago del pedido.

    Puede tener:

    • método de pago.
    • estado del pago.
    • importe.
    • fecha de pago.

    Clase Usuario

    La clase Usuario representa a quien accede al sistema.

    Puede tener distintos roles:

    • ADMIN.
    • GESTOR.
    • CLIENTE.

    En la parte privada nos interesan especialmente los usuarios administradores y gestores.


    9. Diagrama de base de datos

    El diagrama de base de datos representa cómo se guardará la información en tablas.

    Aunque el diagrama de clases y el diagrama de base de datos están relacionados, no son exactamente lo mismo.

    El diagrama de clases representa la estructura del programa en Java.

    El diagrama de base de datos representa cómo se almacenan los datos en MySQL, MariaDB u otro sistema similar.

    Tabla productos

    La tabla principal será productos.

    Contendrá campos como:

    • id_producto.
    • id_categoria.
    • id_profesion.
    • id_coleccion.
    • id_proveedor.
    • id_clase_envio.
    • nombre.
    • sku.
    • precio.
    • precio_oferta.
    • stock.
    • edad_recomendada.
    • descripcion_corta.
    • descripcion_completa.
    • destacado.
    • visible.
    • estado.
    • fecha_creacion.

    Esta tabla tendrá varias claves foráneas para relacionarse con otras tablas.

    Tabla categorias

    La tabla categorias guardará las categorías comerciales de la tienda.

    Campos principales:

    • id_categoria.
    • nombre.
    • descripcion.
    • icono.
    • activa.

    Tabla profesiones

    La tabla profesiones guardará las profesiones disponibles.

    Campos principales:

    • id_profesion.
    • nombre.
    • descripcion.
    • icono.

    Tabla imagenes_producto

    La tabla imagenes_producto guardará las imágenes asociadas a cada producto.

    Campos principales:

    • id_imagen.
    • id_producto.
    • url.
    • texto_alternativo.
    • principal.
    • orden.

    Esta tabla tiene una relación de uno a muchos con productos: un producto puede tener muchas imágenes.

    Tabla etiquetas

    La tabla etiquetas guardará etiquetas reutilizables.

    Como la relación entre productos y etiquetas es de muchos a muchos, necesitaremos una tabla intermedia llamada producto_etiqueta.

    Tabla clientes

    La tabla clientes guardará la información de los compradores.

    Campos principales:

    • id_cliente.
    • nombre.
    • apellidos.
    • email.
    • teléfono.
    • fecha_alta.

    Tabla direcciones

    La tabla direcciones permitirá guardar una o varias direcciones por cliente.

    Campos principales:

    • id_direccion.
    • id_cliente.
    • calle.
    • ciudad.
    • provincia.
    • codigo_postal.
    • país.

    Tabla pedidos

    La tabla pedidos guardará la información general de cada pedido.

    Campos principales:

    • id_pedido.
    • id_cliente.
    • id_direccion.
    • fecha.
    • estado.
    • subtotal.
    • gastos_envio.
    • total.

    Tabla lineas_pedido

    La tabla lineas_pedido guardará los productos incluidos en cada pedido.

    Campos principales:

    • id_linea.
    • id_pedido.
    • id_producto.
    • cantidad.
    • precio_unitario.
    • subtotal.

    Tabla pagos

    La tabla pagos guardará la información de pago del pedido.

    Campos principales:

    • id_pago.
    • id_pedido.
    • metodo.
    • estado.
    • importe.
    • fecha_pago.

    Tabla promociones

    La tabla promociones permitirá gestionar códigos de descuento o promociones.

    Campos principales:

    • id_promocion.
    • nombre.
    • codigo.
    • descuento.
    • fecha_inicio.
    • fecha_fin.
    • activa.

    Como una promoción puede aplicarse a varios productos, y un producto puede tener varias promociones, usaremos una tabla intermedia llamada producto_promocion.


    10. Fases del proyecto

    Para que el trabajo sea más ordenado, dividiremos el proyecto en varias fases.

    Fase 1: Comprensión del proyecto

    En esta fase analizaremos qué queremos construir.

    Responderemos preguntas como:

    • ¿Qué es Mundo Oficios?
    • ¿Qué usuarios tendrá?
    • ¿Qué productos se venderán?
    • ¿Qué partes tendrá la web?
    • ¿Qué necesita el administrador?
    • ¿Qué necesita el cliente?

    El objetivo de esta fase es entender el problema antes de diseñar o programar.

    Fase 2: Diseño visual en Figma

    En esta fase usaremos Figma para diseñar las pantallas principales.

    Trabajaremos:

    • Home pública.
    • Login de la parte privada.
    • Pantalla de alta de producto.
    • Elementos reutilizables.
    • Botones.
    • Tarjetas.
    • Formularios.
    • Menús.
    • Espaciados.
    • Colores.
    • Tipografía.

    El objetivo es que los alumnos entiendan que antes de programar una pantalla conviene diseñarla.

    Figma nos permite pensar la experiencia del usuario sin preocuparnos todavía por el código.

    Fase 3: Casos de uso

    En esta fase identificaremos qué puede hacer cada actor dentro del sistema.

    Trabajaremos con el diagrama de casos de uso para representar:

    • Visitante.
    • Cliente.
    • Administrador.
    • Pasarela de pago.

    El objetivo es comprender las funcionalidades principales de la aplicación.

    Fase 4: Diagrama de clases

    En esta fase pasaremos del análisis funcional a la estructura orientada a objetos.

    Diseñaremos las clases Java que representarán el sistema:

    • Producto.
    • Categoría.
    • Profesión.
    • ImagenProducto.
    • Cliente.
    • Pedido.
    • LíneaPedido.
    • Pago.
    • Usuario.

    El objetivo es entender cómo se transforma una idea de negocio en clases, atributos, métodos y relaciones.

    Fase 5: Diseño de base de datos

    En esta fase diseñaremos las tablas necesarias para almacenar la información.

    Trabajaremos con:

    • Claves primarias.
    • Claves foráneas.
    • Relaciones uno a muchos.
    • Relaciones muchos a muchos.
    • Tablas intermedias.
    • Tipos de datos.
    • Normalización básica.

    El objetivo es que los alumnos comprendan que la base de datos debe reflejar correctamente la estructura de la aplicación.

    Fase 6: Implementación de clases Java

    Una vez diseñado el modelo, podremos empezar a programar las clases Java.

    Por ejemplo:

    • Producto.java.
    • Categoria.java.
    • Profesion.java.
    • Cliente.java.
    • Pedido.java.
    • LineaPedido.java.

    Al principio pueden ser clases sencillas con atributos, constructores, getters, setters y algunos métodos básicos.

    Después podremos avanzar hacia una estructura más completa.

    Fase 7: Formularios web

    En esta fase empezaremos a transformar el diseño en páginas reales.

    Trabajaremos formularios como:

    • Login.
    • Alta de producto.
    • Registro de cliente.
    • Edición de producto.

    El formulario de alta de producto será especialmente importante, porque conectará con la lógica de productos de la aplicación.

    Fase 8: Conexión con base de datos

    En esta fase conectaremos la aplicación Java con la base de datos.

    Dependiendo del nivel del grupo, podremos hacerlo con:

    • JDBC.
    • DAO.
    • Servlets.
    • HTML o plantillas.
    • Frameworks más avanzados si procede.

    El objetivo será guardar, consultar, modificar y eliminar productos desde la base de datos.

    Fase 9: Panel privado funcional

    En esta fase construiremos la parte privada.

    El administrador podrá:

    • Iniciar sesión.
    • Ver productos.
    • Crear productos.
    • Editar productos.
    • Desactivar productos.
    • Subir o asignar imágenes.
    • Gestionar categorías.
    • Ver pedidos.

    No es necesario hacer todo perfecto desde el principio. Lo importante es avanzar por versiones.

    Fase 10: Revisión, pruebas y mejoras

    En la última fase revisaremos el proyecto.

    Comprobaremos:

    • Que las pantallas funcionan.
    • Que los formularios envían datos correctamente.
    • Que se validan los campos importantes.
    • Que la base de datos guarda la información.
    • Que las relaciones están bien planteadas.
    • Que el código está organizado.
    • Que el diseño es coherente.

    También podremos plantear mejoras futuras.


    11. Versión mínima del proyecto

    Como el proyecto puede crecer mucho, conviene definir una versión mínima.

    La versión mínima debería permitir:

    • Ver una home pública.
    • Ver un catálogo básico.
    • Entrar al panel privado.
    • Dar de alta productos.
    • Listar productos.
    • Editar productos.
    • Desactivar productos.
    • Guardar productos en base de datos.

    Con eso ya tendríamos una aplicación bastante completa para trabajar conceptos esenciales.

    No hace falta implementar desde el primer momento pagos reales, estadísticas avanzadas o gestión completa de clientes.


    12. Versión ampliada del proyecto

    Una vez terminada la versión mínima, se pueden añadir mejoras.

    Por ejemplo:

    • Carrito de compra.
    • Registro de clientes.
    • Gestión de pedidos.
    • Subida real de imágenes.
    • Buscador de productos.
    • Filtros por categoría.
    • Filtros por profesión.
    • Promociones y códigos de descuento.
    • Productos destacados.
    • Gestión de stock.
    • Panel de estadísticas.
    • Control de roles.
    • Validaciones avanzadas.
    • Diseño responsive.
    • API REST.
    • Integración con pasarela de pago simulada.

    Estas mejoras nos permitirían convertir el proyecto en una aplicación mucho más completa.


    13. Relación entre diseño, Java y base de datos

    Uno de los puntos más importantes de este proyecto es entender cómo se conectan las diferentes partes.

    Por ejemplo, en el diseño de Figma tenemos un formulario con el campo:

    Nombre del producto

    En Java ese dato puede corresponder al atributo:

    nombre

    Dentro de la clase:

    Producto

    Y en la base de datos se guardará en la columna:

    nombre

    Dentro de la tabla:

    productos

    Este mismo razonamiento se repite con otros campos:

    • Precio.
    • Stock.
    • Categoría.
    • Profesión.
    • Descripción.
    • Estado.
    • Visible.
    • Destacado.

    Así los alumnos pueden ver que el diseño no está separado del código. Lo que se dibuja en Figma después se convierte en HTML, formularios, clases Java y columnas de base de datos.


    14. Ejemplo de flujo: alta de producto

    Vamos a pensar en un ejemplo concreto.

    Un administrador quiere dar de alta un nuevo producto llamado Leo Bombero.

    Paso 1: Accede al panel privado

    El administrador entra en la pantalla de login e introduce su correo y contraseña.

    Si los datos son correctos, accede al panel.

    Paso 2: Entra en productos

    Dentro del menú lateral, pulsa en la opción Productos.

    Desde ahí selecciona la opción para crear un nuevo producto.

    Paso 3: Rellena el formulario

    Introduce los datos:

    • Nombre: Leo Bombero.
    • SKU: BOM-001.
    • Precio: 12,95 €.
    • Precio oferta: 9,95 €.
    • Categoría: Emergencias.
    • Profesión: Bombero.
    • Stock: 50.
    • Edad recomendada: 3+ años.
    • Descripción corta.
    • Descripción completa.
    • Etiquetas.
    • Imágenes.

    Paso 4: Guarda o publica

    El administrador puede guardar el producto como borrador o publicarlo directamente.

    Si lo publica, el producto pasará a estar visible en la tienda pública.

    Paso 5: El cliente lo ve en la tienda

    Un visitante o cliente entra en la web, ve el catálogo, filtra por emergencias y encuentra el producto Leo Bombero.

    Este ejemplo nos ayuda a conectar varias partes del proyecto:

    • Login.
    • Panel privado.
    • Formulario.
    • Producto.
    • Base de datos.
    • Catálogo público.

    15. Organización recomendada para el proyecto Java

    Cuando pasemos a Java, podemos organizar el proyecto por paquetes.

    Una estructura sencilla podría ser:

    src/
    ├── modelo/
    │ ├── Producto.java
    │ ├── Categoria.java
    │ ├── Profesion.java
    │ ├── ImagenProducto.java
    │ ├── Cliente.java
    │ ├── Pedido.java
    │ └── LineaPedido.java
    │
    ├── dao/
    │ ├── ProductoDAO.java
    │ ├── CategoriaDAO.java
    │ └── ClienteDAO.java
    │
    ├── controlador/
    │ ├── ProductoServlet.java
    │ ├── LoginServlet.java
    │ └── PedidoServlet.java
    │
    ├── util/
    │ └── ConexionBD.java
    │
    └── vista/
    ├── index.html
    ├── login.html
    ├── alta-producto.html
    └── listado-productos.html

    Esta organización separa responsabilidades:

    modelo contiene las clases principales.

    dao contiene las clases que trabajan con la base de datos.

    controlador contiene los servlets o controladores.

    util contiene clases auxiliares, como la conexión a base de datos.

    vista contiene las páginas HTML o plantillas.


    16. Posibles ampliaciones

    Los alumnos que avancen más rápido pueden añadir funcionalidades extra.

    Algunas ideas son:

    Buscador de productos

    Permitir buscar productos por nombre, profesión o categoría.

    Filtros avanzados

    Filtrar por:

    • Precio.
    • Categoría.
    • Profesión.
    • Edad recomendada.
    • Disponibilidad.
    • Producto destacado.

    Subida real de imágenes

    Permitir subir imágenes desde el formulario y guardarlas en el servidor.

    Control de roles

    Diferenciar permisos entre administrador y gestor.

    Por ejemplo:

    • El administrador puede gestionar usuarios.
    • El gestor solo puede gestionar productos y pedidos.

    Panel de estadísticas

    Mostrar datos como:

    • Número de productos.
    • Productos con poco stock.
    • Pedidos pendientes.
    • Ventas del mes.
    • Categorías más vendidas.

    Carrito completo

    Implementar un carrito con:

    • Añadir producto.
    • Modificar cantidad.
    • Eliminar producto.
    • Calcular total.
    • Confirmar pedido.

    API REST

    Crear una API para que el frontend pueda consultar productos desde Java.


    17. Qué aprenderemos realmente con este proyecto

    Aunque el proyecto se presenta como una tienda de muñecos, en realidad estamos trabajando conceptos aplicables a muchas aplicaciones web.

    Lo que aprendamos aquí se puede aplicar después a:

    • Una tienda de ropa.
    • Una tienda de videojuegos.
    • Una biblioteca.
    • Un sistema de reservas.
    • Una plataforma de cursos.
    • Un inventario de material.
    • Un sistema de gestión de alumnos.
    • Una aplicación de pedidos.

    La temática de los muñecos nos ayuda a que el proyecto sea visual y fácil de entender, pero la estructura técnica es la de una aplicación web real.


    18. Consejos

    Antes de empezar a programar, es importante entender bien el proyecto.

    No hay que lanzarse directamente al código sin pensar.

    Un buen desarrollo suele seguir este orden:

    Primero entendemos qué queremos construir.

    Después diseñamos las pantallas.

    Luego analizamos los casos de uso.

    Después pensamos las clases.

    Luego diseñamos la base de datos.

    Finalmente empezamos a programar.

    Si seguimos este proceso, el proyecto será más ordenado y será más fácil detectar errores.

    También es importante no intentar hacerlo todo de golpe. Una aplicación grande se construye por partes.

    Primero hacemos una versión sencilla que funcione. Después vamos añadiendo mejoras.


    19. Conclusión

    El proyecto Mundo Oficios nos permitirá trabajar un caso completo de desarrollo de aplicación web.

    Partiremos de una idea sencilla: una tienda online de muñecos por profesiones.

    A partir de esa idea iremos construyendo todo lo necesario:

    • Diseño visual de la web.
    • Prototipo en Figma.
    • Home pública.
    • Login privado.
    • Panel de administración.
    • Alta de productos.
    • Diagrama de casos de uso.
    • Diagrama de clases.
    • Diagrama de base de datos.
    • Clases Java.
    • Formularios.
    • Conexión con base de datos.
    • Gestión de productos.

    El objetivo final no es solo tener una aplicación funcionando, sino comprender el proceso completo que hay detrás de un proyecto web.

    Este proyecto nos va a permitir unir diseño, análisis y programación en un mismo trabajo, acercándonos a la forma en la que se desarrollan aplicaciones reales.


    Descargas

  • 1.1 – Presentación del curso de programación con Java

    1.1 – Presentación del curso de programación con Java

    Audio del tema
    Presentación del curso en audio (IA)

    1. Presentación del curso de programación con Java

    Bienvenido al curso de programación con Java. Este curso está pensado para aprender a programar desde la base, empezando por los conceptos más sencillos y avanzando poco a poco hasta llegar a la programación orientada a objetos, uno de los pilares fundamentales de Java y de muchos lenguajes modernos.

    A lo largo del curso no vamos a limitarnos a memorizar instrucciones ni a copiar código sin entenderlo. El objetivo principal es aprender a pensar como programadores. Esto significa aprender a analizar problemas, dividirlos en partes más pequeñas, plantear soluciones ordenadas y convertir esas soluciones en programas que pueda ejecutar un ordenador.

    Java será el lenguaje que utilizaremos para aprender estos conceptos. Es un lenguaje muy utilizado en el mundo profesional, especialmente en aplicaciones de empresa, aplicaciones web, aplicaciones móviles, sistemas de gestión, herramientas internas y muchos otros tipos de software. Además, Java es un lenguaje muy adecuado para aprender programación porque obliga a trabajar de forma ordenada y ayuda a comprender muy bien conceptos importantes como variables, condiciones, bucles, funciones, clases, objetos, herencia y estructuras de datos.

    Durante el curso utilizaremos Eclipse como entorno de desarrollo. Eclipse es un IDE, es decir, un programa que nos ayuda a escribir, organizar, ejecutar y depurar nuestro código. Aunque al principio puede parecer una herramienta con muchas opciones, poco a poco iremos usando solamente las partes necesarias. La idea no es aprender Eclipse por aprender Eclipse, sino usarlo como herramienta para programar mejor.

    Este primer curso será la base de una formación más amplia. Después de aprender los fundamentos de Java, se podrá continuar con tecnologías más avanzadas como Java EE y posteriormente Spring, que son herramientas muy utilizadas para crear aplicaciones web y sistemas empresariales. Por eso es importante construir ahora una base sólida. Si entendemos bien los fundamentos, todo lo que venga después será mucho más fácil de asimilar.

    Programar no consiste en saber todas las instrucciones de memoria. De hecho, incluso los programadores profesionales consultan documentación, buscan ejemplos y revisan código continuamente. Lo importante es comprender cómo se resuelven los problemas y cómo se estructura un programa. Este curso pretende ayudarte precisamente en eso: a construir una forma de pensar lógica, ordenada y práctica.

    Al principio trabajaremos con programas sencillos. Veremos cómo mostrar mensajes por pantalla, cómo pedir datos al usuario, cómo guardar información en variables y cómo tomar decisiones dentro de un programa. Después incorporaremos bucles para repetir acciones, métodos para organizar mejor el código y arrays para trabajar con conjuntos de datos.

    Más adelante entraremos en la programación orientada a objetos. En ese momento empezaremos a representar elementos del mundo real mediante clases y objetos. Por ejemplo, podremos crear una clase Alumno, una clase Producto, una clase Coche o una clase Reserva. Cada una tendrá sus propios datos y sus propios comportamientos. Esta forma de programar permite crear aplicaciones más grandes, organizadas y fáciles de mantener.

    Al final del curso también veremos una introducción a algunos tipos abstractos de datos, como pilas, colas, listas y una pequeña introducción a grafos. No se trata todavía de estudiarlos con una profundidad matemática avanzada, sino de entender para qué sirven y por qué son importantes en programación.

    Este curso requiere práctica. Leer los apuntes ayuda, ver vídeos ayuda, escuchar explicaciones ayuda, pero se aprende a programar programando. Es normal equivocarse, encontrarse errores, no entender algo a la primera o tener que repetir un ejercicio varias veces. Eso forma parte del proceso. Cada error corregido ayuda a mejorar.

    El objetivo final es que el alumno no solo sepa escribir pequeños programas en Java, sino que empiece a adquirir una mentalidad de desarrollador: analizar, probar, corregir, mejorar y documentar sus soluciones.


    2. Qué es programar

    Programar es darle instrucciones a un ordenador para que realice una tarea. Dicho así parece algo sencillo, pero detrás de esa idea hay una habilidad muy importante: saber transformar un problema en una serie de pasos claros, ordenados y precisos.

    Un ordenador no interpreta las cosas como una persona. Las personas somos capaces de entender frases incompletas, deducir información por contexto o improvisar soluciones. Un ordenador, en cambio, necesita instrucciones concretas. Si una instrucción está mal escrita, si falta un paso o si el orden no es correcto, el programa no funcionará como esperamos.

    Por ejemplo, imaginemos que queremos explicar a una persona cómo preparar un café. Podríamos decirle: “hazme un café”. Si esa persona sabe usar la cafetera, probablemente entenderá lo que queremos. Pero si tuviéramos que explicárselo a un ordenador o a una máquina completamente automática, tendríamos que ser mucho más precisos.

    Tendríamos que indicar pasos como comprobar si hay agua, comprobar si hay café, encender la máquina, colocar el vaso, esperar a que termine el proceso y apagarla. Programar consiste precisamente en eso: describir un proceso de forma tan clara que una máquina pueda ejecutarlo.

    En programación trabajamos constantemente con datos. Un programa puede recibir información, guardarla, modificarla, compararla y mostrar un resultado. Por ejemplo, un programa puede pedir la edad de una persona y decidir si es mayor de edad. También puede calcular el precio total de una compra, comprobar una contraseña, ordenar una lista de nombres o gestionar las reservas de un hotel.

    Un programa no suele ser una única instrucción aislada. Normalmente está formado por muchas instrucciones que trabajan juntas. Algunas sirven para guardar información, otras para tomar decisiones, otras para repetir tareas y otras para organizar mejor el código.

    Por ejemplo, si queremos hacer un programa que calcule si un alumno ha aprobado, podríamos pensar en algo como esto:

    int nota = 7;

    if (nota >= 5) {
    System.out.println("El alumno ha aprobado");
    } else {
    System.out.println("El alumno ha suspendido");
    }

    Este pequeño ejemplo ya muestra varias ideas importantes. Hay una variable llamada nota, que guarda un valor numérico. Después hay una condición que comprueba si esa nota es mayor o igual que 5. Según el resultado de esa comprobación, el programa muestra un mensaje u otro.

    Aunque el código sea corto, ya estamos haciendo algo esencial en programación: tomar una decisión. Los programas reales están llenos de decisiones de este tipo. Una aplicación bancaria decide si una operación es válida o no. Una tienda online decide si hay stock suficiente. Un videojuego decide si un personaje ha perdido vida. Una aplicación de reservas decide si una habitación está disponible.

    Programar también implica aprender a dividir los problemas. Cuando un problema es pequeño, se puede resolver de forma directa. Pero cuando el programa crece, necesitamos organizarlo mejor. No podemos escribir todo el código mezclado sin ningún orden. Por eso existen funciones, métodos, clases, paquetes y estructuras que nos ayudan a mantener el programa limpio y comprensible.

    Una parte importante de aprender a programar es aceptar que los errores son normales. Cuando un programa falla, no significa necesariamente que seamos malos programando. Significa que hay algo que revisar. Puede ser un error de sintaxis, una variable mal escrita, una condición mal planteada o una lógica incorrecta.

    Los errores forman parte del aprendizaje. De hecho, una de las habilidades más importantes de un programador es saber leer errores, buscar la causa y corregirlos. Programar no es escribir código perfecto a la primera. Programar es construir una solución, probarla, detectar problemas y mejorarla.

    También es importante entender que programar no es solo escribir código. Antes de escribir una línea, muchas veces hay que pensar. Hay que entender qué se quiere conseguir, qué datos necesitamos, qué pasos hay que seguir y qué resultado esperamos obtener. Si no entendemos el problema, difícilmente podremos resolverlo bien con código.

    Por eso, en este curso no solo escribiremos programas. También aprenderemos a analizar ejercicios, plantear soluciones y explicar lo que hace nuestro código. Esa capacidad de razonar es lo que realmente permite avanzar.


    3. Qué es Java y para qué se utiliza

    Java es un lenguaje de programación creado para desarrollar aplicaciones de forma ordenada, segura y portable. Es uno de los lenguajes más utilizados en el mundo profesional y ha sido durante muchos años una referencia en el desarrollo de software.

    Una de las características más importantes de Java es que permite escribir programas que pueden ejecutarse en diferentes sistemas operativos. Un programa Java puede funcionar en Windows, Linux o macOS siempre que el sistema tenga instalado el entorno adecuado para ejecutarlo. Esta idea se suele resumir con la frase: “escribe una vez, ejecuta en cualquier lugar”.

    Para conseguir esto, Java no funciona exactamente igual que otros lenguajes que se compilan directamente para un sistema concreto. Cuando escribimos código Java, ese código se compila y se transforma en un formato intermedio llamado bytecode. Ese bytecode se ejecuta sobre la Máquina Virtual de Java, conocida como JVM.

    La JVM actúa como una capa intermedia entre nuestro programa y el sistema operativo. Gracias a ella, el mismo programa puede ejecutarse en distintos entornos sin tener que reescribirlo desde cero.

    De forma simplificada, el proceso sería el siguiente:

    Primero escribimos un archivo con código Java, por ejemplo:

    public class HolaMundo {
    public static void main(String[] args) {
    System.out.println("Hola, mundo");
    }
    }

    Después ese código se compila. Si no hay errores, se genera un archivo intermedio que puede ejecutar la JVM. Finalmente, la máquina virtual interpreta y ejecuta el programa.

    Al principio, muchas partes de este código pueden parecer extrañas. Es normal. Todavía no es necesario entenderlo todo en profundidad. Más adelante veremos qué significa public class, qué es main, por qué se usan llaves { } y cómo se organiza un programa Java. Ahora lo importante es quedarse con la idea general: Java nos permite escribir instrucciones que el ordenador puede ejecutar.

    Java se utiliza en muchos ámbitos. Uno de los más importantes es el desarrollo de aplicaciones empresariales. Muchas empresas utilizan Java para crear sistemas de gestión, aplicaciones internas, plataformas web, servicios backend, aplicaciones bancarias, herramientas de administración y sistemas que necesitan ser estables y escalables.

    También se ha utilizado mucho en el desarrollo de aplicaciones Android. Aunque hoy en día Android también utiliza Kotlin, Java sigue siendo un lenguaje importante en ese ecosistema y muchos proyectos existentes están escritos total o parcialmente en Java.

    Otro uso importante de Java está en el desarrollo de aplicaciones web. En este curso empezaremos por los fundamentos del lenguaje, pero más adelante se puede continuar con Java EE, Servlets, JSP, Spring Boot y otras tecnologías relacionadas con el desarrollo de aplicaciones web y servicios.

    Java también se utiliza en educación porque permite aprender muy bien los conceptos fundamentales de la programación orientada a objetos. Aunque al principio puede parecer más estricto que otros lenguajes, esa exigencia ayuda a adquirir buenos hábitos. Java obliga a declarar tipos de datos, organizar el código en clases y seguir una estructura clara.

    Por ejemplo, en Java una variable debe tener un tipo. Si queremos guardar un número entero, podemos escribir:

    int edad = 20;

    Si queremos guardar texto, usamos String:

    String nombre = "Ana";

    Y si queremos guardar un valor verdadero o falso, usamos boolean:

    boolean aprobado = true;

    Esta forma de trabajar ayuda a entender qué tipo de información estamos manejando en cada momento. El programa sabe que edad es un número, que nombre es texto y que aprobado representa una condición lógica.

    Java es un lenguaje orientado a objetos. Esto significa que permite organizar el código utilizando clases y objetos. Una clase puede entenderse como un molde o plantilla. A partir de ese molde podemos crear objetos concretos.

    Por ejemplo, podríamos tener una clase Alumno:

    public class Alumno {
    String nombre;
    int edad;
    double notaMedia;
    }

    Esa clase describe qué datos puede tener un alumno. Después, en un programa, podríamos crear alumnos concretos con sus propios valores. Esta forma de trabajar se parece bastante a cómo organizamos la realidad: tenemos entidades, características y acciones.

    La programación orientada a objetos será una parte muy importante del curso, pero antes de llegar ahí necesitamos dominar la base: variables, operadores, condiciones, bucles, métodos y arrays. Intentar aprender objetos sin entender bien estos conceptos sería como intentar construir una casa sin tener buenos cimientos.

    Java también tiene una gran comunidad y muchísima documentación. Esto es importante porque ningún programador trabaja completamente aislado. Cuando aprendemos un lenguaje, necesitamos ejemplos, documentación oficial, foros, librerías y herramientas. Java cuenta con un ecosistema muy amplio, lo que lo convierte en una opción sólida para aprender y para trabajar profesionalmente.

    Otra ventaja de Java es que tiene una sintaxis parecida a otros lenguajes muy utilizados, como C#, JavaScript, C++ o PHP en algunos aspectos. Esto significa que, aunque cada lenguaje tiene sus propias características, aprender Java facilita después el aprendizaje de otros lenguajes. Muchos conceptos se repiten: variables, condiciones, bucles, funciones, clases, objetos y estructuras de datos.

    En este curso, Java será nuestro medio para aprender programación. No se trata solamente de aprender comandos de Java, sino de usar Java para comprender cómo se construye un programa desde cero. Primero haremos ejercicios pequeños y controlados. Después iremos aumentando la dificultad. Con el tiempo, los programas tendrán más clases, más métodos y más lógica.

    El objetivo no es correr, sino avanzar con seguridad. La programación requiere práctica constante, paciencia y una mentalidad de mejora. Java puede parecer exigente al principio, pero precisamente por eso es una herramienta excelente para aprender bien.

    Al terminar esta primera parte del curso, el alumno debería ser capaz de leer y escribir programas básicos en Java, entender la estructura de un programa, utilizar variables, condiciones, bucles, métodos, arrays y comenzar a trabajar con clases y objetos. Esa base será imprescindible para continuar después con tecnologías más avanzadas del ecosistema Java.

  • 1.2 – Alcance del curso

    1.2 – Alcance del curso

    Después de esa base inicial, el curso avanzará hacia la programación orientada a objetos, uno de los pilares fundamentales de Java. Aprenderemos a diseñar clases, crear objetos, aplicar encapsulación, trabajar con relaciones entre clases, usar herencia, polimorfismo, clases abstractas e interfaces. La idea no es solo aprender la sintaxis del lenguaje, sino entender cómo se piensa y se organiza una aplicación real.

    En la parte final se introducen conceptos algo más avanzados relacionados con los tipos abstractos de datos, como pilas, colas, listas y una primera aproximación a los grafos. Estos contenidos servirán como puente hacia una comprensión más profunda de las estructuras que se utilizan en programación y prepararán el camino para cursos posteriores.

    Este será el primero de tres grandes módulos. Una vez asentadas las bases de Java, continuaremos con el desarrollo de aplicaciones web mediante Java EE y, posteriormente, con Spring/Spring Boot, donde aplicaremos estos conocimientos en proyectos más completos y cercanos al desarrollo profesional.

    Bloque 1 — Introducción al curso y entorno de trabajo

    1. Presentación del curso de programación con Java
    2. Qué es programar
    3. Qué es Java y para qué se utiliza
    4. Instalación del JDK
    5. Instalación de Eclipse
    6. Configuración inicial de Eclipse
    7. Creación del primer proyecto Java
    8. Estructura básica de un programa Java
    9. Primer programa: Hola Mundo
    10. Compilar, ejecutar y corregir errores básicos

    Bloque 2 — Primeros conceptos de programación

    1. Algoritmos y pensamiento computacional
    2. Instrucciones y flujo de ejecución
    3. Datos, memoria y variables
    4. Tipos de datos primitivos en Java
    5. Constantes
    6. Conversión de tipos
    7. Entrada de datos por teclado con Scanner
    8. Salida de datos por consola
    9. Comentarios y buenas prácticas iniciales
    10. Errores comunes al empezar a programar

    Bloque 3 — Operadores y expresiones

    1. Operadores aritméticos
    2. Operadores de asignación
    3. Operadores relacionales
    4. Operadores lógicos
    5. Incremento y decremento
    6. Prioridad de operadores
    7. Expresiones simples y compuestas
    8. Ejercicios básicos de cálculo
    9. Validación de expresiones
    10. Depuración básica en Eclipse

    Bloque 4 — Estructuras condicionales

    1. Toma de decisiones en programación
    2. Condicional if
    3. Condicional if else
    4. Condicionales anidados
    5. Condiciones múltiples
    6. Operadores lógicos en condiciones
    7. Estructura switch
    8. Menús básicos con switch
    9. Validación de datos con condicionales
    10. Ejercicios prácticos de decisiones

    Bloque 5 — Bucles y control de flujo

    1. Introducción a los bucles
    2. Bucle while
    3. Bucle do while
    4. Bucle for
    5. Contadores y acumuladores
    6. Bucles anidados
    7. Control de bucles con break
    8. Control de bucles con continue
    9. Validación repetitiva de datos
    10. Ejercicios prácticos con bucles

    Bloque 6 — Métodos y organización del código

    1. Qué es un método
    2. Métodos sin parámetros y sin retorno
    3. Métodos con parámetros
    4. Métodos con valor de retorno
    5. Parámetros y argumentos
    6. Variables locales
    7. Alcance de las variables
    8. Sobrecarga de métodos
    9. Organización del código en métodos
    10. Ejercicios prácticos con métodos

    Bloque 7 — Arrays y estructuras básicas de datos

    1. Introducción a los arrays
    2. Declaración y creación de arrays
    3. Recorrido de arrays
    4. Carga de datos en arrays
    5. Búsqueda de elementos
    6. Cálculos con arrays
    7. Arrays de cadenas de texto
    8. Arrays multidimensionales
    9. Matrices en Java
    10. Ejercicios prácticos con arrays y matrices

    Bloque 8 — Cadenas de texto y clases básicas de Java

    1. La clase String
    2. Métodos principales de String
    3. Comparación de cadenas
    4. Conversión entre texto y números
    5. La clase Math
    6. Números aleatorios con Random
    7. Fechas básicas con Java
    8. Formateo básico de datos
    9. Uso de clases de utilidad
    10. Ejercicios prácticos con cadenas y utilidades

    Bloque 9 — Introducción a la programación orientada a objetos

    1. Qué es la programación orientada a objetos
    2. Clases y objetos
    3. Atributos
    4. Métodos
    5. Creación de objetos
    6. Acceso a atributos y métodos
    7. Estado y comportamiento
    8. Diseño básico de clases
    9. Diagramas sencillos de clases
    10. Primeros ejercicios con objetos

    Bloque 10 — Constructores, encapsulación y organización de clases

    1. Constructores
    2. Constructor por defecto
    3. Constructores con parámetros
    4. Sobrecarga de constructores
    5. Encapsulación
    6. Modificadores de acceso
    7. Métodos get y set
    8. Uso de this
    9. Separación de clases en archivos
    10. Ejercicios prácticos de encapsulación

    Bloque 11 — Relaciones entre clases

    1. Objetos como atributos
    2. Asociación entre clases
    3. Composición
    4. Agregación
    5. Colecciones de objetos usando arrays
    6. Clases principales y clases auxiliares
    7. Diseño de pequeños modelos de datos
    8. Programas con varias clases
    9. Diagramas UML básicos
    10. Proyecto guiado con varias clases

    Bloque 12 — Herencia y reutilización de código

    1. Introducción a la herencia
    2. Clases padre y clases hijas
    3. Uso de extends
    4. Herencia de atributos y métodos
    5. Sobrescritura de métodos
    6. Uso de super
    7. Constructores en herencia
    8. Jerarquías de clases
    9. Ventajas y límites de la herencia
    10. Ejercicios prácticos con herencia

    Bloque 13 — Polimorfismo, clases abstractas e interfaces

    1. Introducción al polimorfismo
    2. Referencias de tipo padre
    3. Sobrescritura y comportamiento dinámico
    4. Conversión entre tipos de objetos
    5. Clases abstractas
    6. Métodos abstractos
    7. Interfaces
    8. Implementación de interfaces
    9. Diferencias entre clase abstracta e interfaz
    10. Ejercicios prácticos de polimorfismo

    Bloque 14 — Gestión de errores y excepciones

    1. Errores de compilación
    2. Errores de ejecución
    3. Errores lógicos
    4. Introducción a las excepciones
    5. Bloque try catch
    6. Captura de varias excepciones
    7. Bloque finally
    8. Lanzamiento de excepciones
    9. Validación robusta de programas
    10. Ejercicios prácticos con excepciones

    Bloque 15 — Colecciones básicas de Java

    1. Limitaciones de los arrays
    2. Introducción a las colecciones
    3. ArrayList
    4. Recorrido de colecciones
    5. Búsqueda en colecciones
    6. Eliminación de elementos
    7. Colecciones de objetos
    8. Ordenación básica
    9. Diferencias entre arrays y colecciones
    10. Ejercicios prácticos con ArrayList

    Bloque 16 — Proyecto final del curso

    1. Planteamiento del proyecto final
    2. Análisis de requisitos
    3. Diseño de clases
    4. Creación del proyecto en Eclipse
    5. Desarrollo del modelo de datos
    6. Desarrollo de la lógica del programa
    7. Creación de menús por consola
    8. Validación de entradas
    9. Pruebas y corrección de errores
    10. Presentación del proyecto final

    Bloque 17 — Introducción a los tipos abstractos de datos

    1. Qué es un tipo abstracto de datos
    2. Diferencia entre estructura lógica y estructura física
    3. Estructuras estáticas
    4. Estructuras dinámicas
    5. Pilas estáticas
    6. Pilas dinámicas
    7. Colas estáticas
    8. Colas dinámicas
    9. Listas enlazadas básicas
    10. Listas simplemente enlazadas
    11. Listas doblemente enlazadas
    12. Comparación entre arrays, listas, pilas y colas
    13. Introducción a los árboles
    14. Introducción a los grafos
    15. Representación básica de grafos
    16. Recorrido básico de grafos
    17. Ejercicios introductorios de tipos abstractos de datos
  • 1.3 – Instalación y primeros pasos con Java y Eclipse 📹

    1.3 – Instalación y primeros pasos con Java y Eclipse 📹

    En este tema vamos a preparar el entorno de trabajo que usaremos durante el curso de programación con Java. Antes de empezar a escribir programas necesitamos instalar dos piezas fundamentales: el JDK, que contiene las herramientas necesarias para compilar y ejecutar programas Java, y Eclipse, que será el entorno de desarrollo desde el que escribiremos, organizaremos y probaremos nuestros proyectos.

    Actualmente, Oracle indica que JDK 26 es la versión más reciente de Java y que JDK 25 es la última versión LTS, es decir, una versión de soporte a largo plazo. Para un curso de programación es recomendable trabajar con una versión LTS porque ofrece más estabilidad. También se puede usar JDK 21 LTS si el centro o el profesor quiere mantener compatibilidad con entornos ya instalados.

    Eclipse también se mantiene actualizado y la versión Eclipse IDE 2026-03 incluye soporte para Java 25, además de herramientas para Java, Git, Maven y Gradle.


    1. Instalación del JDK 📹

    Qué es el JDK

    Para poder programar en Java necesitamos instalar el JDK, siglas de Java Development Kit. El JDK es el conjunto de herramientas que permite desarrollar aplicaciones Java. Incluye, entre otras cosas, el compilador, la máquina virtual de Java y diferentes utilidades necesarias para trabajar desde consola o desde un entorno de desarrollo como Eclipse.

    Es importante distinguir tres conceptos:

    Java es el lenguaje de programación.

    JVM, o Java Virtual Machine, es la máquina virtual que ejecuta los programas Java.

    JDK es el paquete completo para desarrolladores. Incluye la JVM, el compilador y otras herramientas.

    Cuando escribimos un programa Java, normalmente lo guardamos en un archivo con extensión .java. Ese archivo contiene código fuente, es decir, código escrito por una persona. Después, el compilador de Java transforma ese archivo en un archivo .class, que contiene bytecode. Ese bytecode será ejecutado por la JVM.

    El proceso básico sería este:

    1. Escribimos un archivo llamado HolaMundo.java.
    2. Lo compilamos.
    3. Se genera un archivo llamado HolaMundo.class.
    4. La JVM ejecuta ese archivo compilado.

    Qué versión instalar

    Para este curso se recomienda instalar una versión LTS de Java. En este momento, la versión recomendada para un entorno nuevo sería JDK 25 LTS, porque Oracle la identifica como la última versión LTS.

    También podemos usar Eclipse Temurin, que es una distribución gratuita y muy utilizada del JDK. Adoptium ofrece descargas de Temurin para distintas versiones LTS, incluyendo JDK 25, JDK 21, JDK 17, JDK 11 y JDK 8.

    Para el alumno, la recomendación sencilla es:

    Instalar JDK 25 LTS, preferiblemente desde Oracle o desde Eclipse Adoptium Temurin.


    Instalación en Windows 📹

    En Windows podemos instalar el JDK descargando el instalador desde la página oficial. El alumno debe elegir la versión correspondiente a su sistema operativo, normalmente Windows x64 Installer.

    https://www.oracle.com/es/java/technologies/downloads/#jdk26-windows

    Una vez descargado el instalador, se ejecuta y se siguen los pasos del asistente. Lo normal es aceptar la ruta de instalación por defecto. Una ruta habitual puede ser parecida a esta:

    C:\Program Files\Java\jdk-25

    Después de instalar el JDK, conviene comprobar que Windows reconoce Java desde la terminal.

    Para ello, abrimos Símbolo del sistema o PowerShell y escribimos:

    java -version

    Deberíamos ver una salida parecida a esta:

    java version "25..."
    Java(TM) SE Runtime Environment ...
    Java HotSpot(TM) 64-Bit Server VM ...

    También debemos comprobar que funciona el compilador:

    javac -version

    El comando java sirve para ejecutar programas Java. El comando javac sirve para compilar archivos .java.

    Si java -version funciona pero javac -version no funciona, normalmente significa que no se ha instalado el JDK completo o que la variable PATH no está bien configurada.


    Variables de entorno en Windows

    En algunos equipos, después de instalar el JDK, Windows no reconoce los comandos java o javac. En ese caso hay que revisar las variables de entorno.

    La variable más importante es PATH. Esta variable le dice al sistema operativo en qué carpetas debe buscar los comandos.

    La carpeta que debemos añadir al PATH suele ser la carpeta bin del JDK. Por ejemplo:

    C:\Program Files\Java\jdk-25\bin

    También se puede crear una variable llamada JAVA_HOME, que apunte a la carpeta principal del JDK:

    C:\Program Files\Java\jdk-25

    Después, en el PATH, se puede añadir:

    %JAVA_HOME%\bin

    Una vez hecho esto, hay que cerrar y volver a abrir la terminal. Si dejamos abierta la terminal antigua, es posible que no detecte los cambios.


    Instalación en macOS

    En macOS también podemos instalar el JDK desde Oracle o desde Eclipse Adoptium. Si se descarga desde la web, normalmente obtendremos un archivo .pkg, que se instala siguiendo el asistente.

    Una vez instalado, abrimos la aplicación Terminal y comprobamos:

    java -version

    Y también:

    javac -version

    Si ambos comandos devuelven una versión, el JDK está instalado correctamente.

    En macOS también se puede comprobar qué versiones de Java están instaladas con:

    /usr/libexec/java_home -V

    Este comando muestra las instalaciones de Java detectadas por el sistema.


    Instalación en Linux

    En Linux podemos instalar Java desde los repositorios de la distribución o descargarlo desde Oracle/Adoptium.

    En Ubuntu o distribuciones basadas en Debian, una instalación sencilla sería:

    sudo apt update
    sudo apt install openjdk-25-jdk

    Si la versión 25 no estuviera disponible en los repositorios de la distribución, se puede instalar una versión LTS disponible, como Java 21:

    sudo apt update
    sudo apt install openjdk-21-jdk

    Después comprobamos:

    java -version
    javac -version

    En Linux también podemos localizar dónde está instalado Java con:

    which java
    which javac

    2. Instalación de Eclipse 📹

    Qué es Eclipse

    Eclipse es un IDE, es decir, un entorno de desarrollo integrado. Un IDE es una aplicación que reúne en un mismo lugar varias herramientas necesarias para programar: editor de código, explorador de proyectos, compilación, ejecución, depuración, resaltado de errores, autocompletado y gestión de librerías.

    Podríamos escribir programas Java usando solamente un editor de texto y la terminal, pero para aprender resulta mucho más cómodo utilizar un IDE. Eclipse nos ayuda a detectar errores, organizar los proyectos y ejecutar el programa con un botón.

    Para este curso nos interesa especialmente la versión Eclipse IDE for Java Developers, que incluye las herramientas esenciales para programar en Java. La página oficial de Eclipse la describe como una distribución con herramientas para desarrollo Java, cliente Git, editor XML e integración con Maven y Gradle.


    Qué versión de Eclipse descargar

    Para este curso podemos usar:

    Eclipse IDE for Java Developers

    Esta versión es suficiente para aprender Java desde cero, trabajar con clases, paquetes, proyectos, consola, depuración y ejercicios de programación.

    Más adelante, cuando el alumno avance hacia Java EE, Servlets, JSP, Maven, servidores y aplicaciones web, puede ser interesante instalar:

    Eclipse IDE for Enterprise Java and Web Developers

    Esta otra versión incluye herramientas adicionales para aplicaciones web, JavaScript, JSP, JPA, Maven, Gradle, Git y desarrollo empresarial.

    Para este primer curso básico de Java, con Eclipse IDE for Java Developers es suficiente.


    Instalación en Windows

    Para instalar Eclipse en Windows, descargamos el instalador desde la página oficial de Eclipse. Una vez descargado, ejecutamos el instalador y seleccionamos:

    Eclipse IDE for Java Developers

    El instalador preguntará dónde queremos instalar Eclipse. Se puede dejar la ruta por defecto. También nos preguntará qué versión de Java queremos usar. Si el JDK está bien instalado, Eclipse debería detectarlo automáticamente.

    Una vez terminado el proceso, podremos iniciar Eclipse desde el menú de inicio o desde el acceso directo creado.


    Instalación en macOS

    En macOS descargamos Eclipse desde la página oficial. Normalmente obtendremos un archivo .dmg. Lo abrimos y copiamos Eclipse a la carpeta Aplicaciones.

    Al abrir Eclipse por primera vez, macOS puede mostrar un aviso de seguridad porque es una aplicación descargada de Internet. Si aparece ese aviso, debemos permitir su ejecución desde los ajustes de seguridad del sistema.


    Instalación en Linux

    En Linux podemos descargar Eclipse desde su página oficial como archivo comprimido, descomprimirlo y ejecutar el programa. Otra opción es usar el instalador oficial de Eclipse.

    Un ejemplo de instalación manual sería:

    cd Descargas
    tar -xzf eclipse-inst-jre-linux64.tar.gz
    cd eclipse-installer
    ./eclipse-inst

    Después seleccionamos:

    Eclipse IDE for Java Developers

    Y seguimos el asistente.


    3. Configuración inicial de Eclipse 📹

    La primera vez que abrimos Eclipse, nos pedirá seleccionar un workspace.

    El workspace es la carpeta donde Eclipse guardará nuestros proyectos. Es importante elegir una ubicación ordenada, porque ahí se irán creando todos los ejercicios del curso.

    Por ejemplo, podemos crear una carpeta llamada:

    CursoJava

    En Windows podría estar en:

    C:\Users\Alumno\Documents\CursoJava

    En macOS o Linux podría estar en:

    /home/alumno/CursoJava

    O en macOS:

    /Users/alumno/CursoJava

    Una buena práctica es no guardar los proyectos en carpetas mezcladas con descargas, escritorio lleno de archivos o rutas difíciles de encontrar.


    Selección del workspace

    Cuando aparezca la ventana de selección de workspace, elegimos la carpeta donde queremos trabajar.

    Podemos marcar la opción:

    Use this as the default and do not ask again

    Esto hará que Eclipse abra siempre ese workspace por defecto.

    Si más adelante queremos cambiar de workspace, podemos hacerlo desde:

    File > Switch Workspace

    Configurar el JDK en Eclipse

    Aunque Eclipse suele detectar automáticamente el JDK instalado, conviene revisar la configuración.

    Vamos a:

    Window > Preferences

    En macOS puede aparecer como:

    Eclipse > Settings

    Después entramos en:

    Java > Installed JREs

    Aquí deberíamos ver el JDK instalado. Es importante que aparezca un JDK y no solamente un JRE. El JRE sirve para ejecutar programas, pero el JDK incluye también las herramientas de desarrollo.

    Si no aparece, podemos añadirlo manualmente con:

    Add > Standard VM

    Y seleccionamos la carpeta donde está instalado el JDK.

    Por ejemplo, en Windows:

    C:\Program Files\Java\jdk-25

    En macOS puede ser algo parecido a:

    /Library/Java/JavaVirtualMachines/jdk-25.jdk/Contents/Home

    En Linux podría ser:

    /usr/lib/jvm/java-25-openjdk-amd64

    Configurar la codificación de texto

    Es recomendable configurar Eclipse para trabajar con UTF-8. Esto evita problemas con tildes, eñes y caracteres especiales.

    Vamos a:

    Window > Preferences > General > Workspace

    Buscamos la opción:

    Text file encoding

    Y seleccionamos:

    UTF-8

    Esto es especialmente importante porque en nuestros programas podemos escribir textos como:

    System.out.println("Hola, ¿qué tal?");

    Si la codificación no está bien configurada, algunos caracteres podrían verse mal.


    Configurar el tamaño de letra

    Para trabajar cómodamente en clase, especialmente si el profesor proyecta la pantalla, podemos aumentar el tamaño de letra del editor.

    La ruta puede variar según la versión, pero normalmente está en:

    Window > Preferences > General > Appearance > Colors and Fonts

    Después buscamos:

    Java > Java Editor Text Font

    Y ajustamos el tamaño.


    Mostrar números de línea

    Los números de línea son muy útiles para corregir errores. Cuando Java muestra un error, normalmente indica en qué línea se ha producido.

    Para activar los números de línea:

    Window > Preferences > General > Editors > Text Editors

    Marcamos:

    Show line numbers

    A partir de ese momento, el editor mostrará un número al lado de cada línea de código.


    4. Creación del primer proyecto Java

    Una vez instalado y configurado Eclipse, vamos a crear nuestro primer proyecto.

    Un proyecto en Eclipse es una carpeta organizada que contiene nuestros archivos Java, configuraciones y recursos. Para cada bloque de ejercicios podemos crear un proyecto diferente, o bien trabajar con un único proyecto organizado por paquetes.

    Para empezar, crearemos un proyecto sencillo.

    Vamos a:

    File > New > Java Project

    Si no aparece directamente, podemos ir a:

    File > New > Other > Java > Java Project

    En el nombre del proyecto escribimos:

    PrimerProyectoJava

    Después revisamos que Eclipse esté usando el JDK correcto.

    En la parte de configuración del proyecto podemos dejar las opciones por defecto. Eclipse creará una carpeta src, donde escribiremos el código fuente.

    Pulsamos:

    Finish

    Y veremos el proyecto en el panel izquierdo, llamado normalmente Package Explorer.


    Crear una clase Java

    Dentro del proyecto vamos a crear una clase.

    Hacemos clic derecho sobre la carpeta src:

    New > Class

    En el nombre de la clase escribimos:

    HolaMundo

    Marcamos la opción:

    public static void main(String[] args)

    Esta opción hace que Eclipse cree automáticamente el método principal del programa.

    Pulsamos:

    Finish

    Eclipse creará un archivo llamado:

    HolaMundo.java

    Ese archivo contendrá una estructura parecida a esta:

    public class HolaMundo {

    public static void main(String[] args) {

    }

    }

    Estructura básica de un programa Java

    Antes de escribir nuestro primer programa completo, vamos a entender la estructura mínima de un programa Java.

    Un programa Java básico suele estar formado por una clase y un método main.

    Ejemplo:

    public class HolaMundo {

    public static void main(String[] args) {
    System.out.println("Hola Mundo");
    }

    }

    Vamos a analizarlo poco a poco.


    La clase

    Esta línea declara una clase:

    public class HolaMundo {

    En Java, casi todo el código se escribe dentro de clases. La clase es una estructura fundamental del lenguaje. Más adelante, cuando estudiemos programación orientada a objetos, veremos las clases con mucho más detalle.

    De momento, podemos pensar que una clase es una especie de contenedor donde escribimos código.

    El nombre de la clase es:

    HolaMundo

    Por norma general, el archivo debe llamarse igual que la clase pública. Por eso, si la clase se llama HolaMundo, el archivo debe llamarse:

    HolaMundo.java

    Esto es importante. Si el archivo no se llama igual que la clase pública, Java mostrará un error.


    Las llaves

    En Java se usan llaves { } para delimitar bloques de código.

    Por ejemplo:

    public class HolaMundo {

    }

    Todo lo que está dentro de esas llaves pertenece a la clase HolaMundo.

    También el método main tiene sus propias llaves:

    public static void main(String[] args) {

    }

    Todo lo que escribamos dentro de esas llaves será parte del método principal.

    Uno de los errores más comunes al empezar es borrar una llave sin querer o colocarla en un sitio incorrecto. Cuando esto ocurre, Eclipse suele marcar errores en varias líneas, aunque el problema real sea una sola llave mal colocada.


    El método main

    El método main es el punto de entrada del programa. Cuando ejecutamos una aplicación Java, Java busca este método para saber por dónde debe empezar.

    La estructura es:

    public static void main(String[] args) {

    }

    Al principio no hace falta memorizar cada palabra, pero sí debemos acostumbrarnos a reconocerlo. Durante las primeras clases lo usaremos constantemente.

    Podemos verlo como la puerta de entrada del programa.

    Cuando damos al botón de ejecutar, Java entra en el método main y empieza a ejecutar las instrucciones que hay dentro, de arriba abajo.


    Instrucciones

    Dentro del método main escribimos instrucciones.

    Por ejemplo:

    System.out.println("Hola Mundo");

    Esta instrucción muestra un texto por pantalla, concretamente en la consola de Eclipse.

    La instrucción termina con punto y coma:

    ;

    En Java, muchas instrucciones terminan con punto y coma. Olvidar el punto y coma es uno de los errores más habituales al empezar.


    Comentarios

    Los comentarios son partes del código que Java ignora. Sirven para dejar explicaciones para nosotros o para otros programadores.

    Comentario de una línea:

    // Esto es un comentario de una línea

    Comentario de varias líneas:

    /*
    Esto es un comentario
    de varias líneas
    */

    Ejemplo completo:

    public class HolaMundo {

    public static void main(String[] args) {
    // Mostramos un mensaje por pantalla
    System.out.println("Hola Mundo");
    }

    }

    Los comentarios son útiles, pero no conviene abusar de ellos. Un buen comentario explica algo que no es evidente, no repite lo mismo que ya dice el código.


    6. Primer programa: Hola Mundo

    El primer programa tradicional en casi cualquier lenguaje de programación es Hola Mundo. Es un programa muy sencillo que sirve para comprobar que el entorno está bien instalado y que somos capaces de crear, compilar y ejecutar código.

    Nuestro programa será este:

    public class HolaMundo {

    public static void main(String[] args) {
    System.out.println("Hola Mundo");
    }

    }

    Cuando lo ejecutemos, veremos en la consola:

    Hola Mundo

    Aunque parezca un programa muy simple, aquí ya están apareciendo varias ideas importantes:

    • Estamos creando una clase.
    • Estamos usando el método principal main.
    • Estamos escribiendo una instrucción.
    • Estamos mostrando información por consola.
    • Estamos usando comillas para escribir texto.
    • Estamos terminando la instrucción con punto y coma.
    • Estamos ejecutando un programa Java real.

    Mostrar varios mensajes

    Podemos escribir más de una instrucción:

    public class HolaMundo {

    public static void main(String[] args) {
    System.out.println("Hola Mundo");
    System.out.println("Estoy aprendiendo Java");
    System.out.println("Este es mi primer programa");
    }

    }

    La salida será:

    Hola Mundo
    Estoy aprendiendo Java
    Este es mi primer programa

    Java ejecuta las instrucciones en orden, desde la primera hasta la última.


    Diferencia entre println y print

    System.out.println muestra un texto y después hace un salto de línea.

    Ejemplo:

    System.out.println("Hola");
    System.out.println("Mundo");

    Salida:

    Hola
    Mundo

    En cambio, System.out.print muestra el texto pero no cambia de línea.

    Ejemplo:

    System.out.print("Hola");
    System.out.print("Mundo");

    Salida:

    HolaMundo

    Si queremos dejar un espacio, tenemos que escribirlo nosotros:

    System.out.print("Hola ");
    System.out.print("Mundo");

    Salida:

    Hola Mundo

    Escribir textos con caracteres especiales

    Los textos en Java se escriben entre comillas dobles:

    System.out.println("Esto es un texto");

    Si queremos escribir comillas dentro del texto, necesitamos usar una barra invertida:

    System.out.println("Me dijo: \"Hola\"");

    Salida:

    Me dijo: "Hola"

    También podemos usar \n para hacer un salto de línea dentro del texto:

    System.out.println("Primera línea\nSegunda línea");

    Salida:

    Primera línea
    Segunda línea

    Y podemos usar \t para insertar una tabulación:

    System.out.println("Nombre\tEdad");
    System.out.println("Ana\t20");
    System.out.println("Luis\t22");

    Salida aproximada:

    Nombre  Edad
    Ana 20
    Luis 22

    Ejemplo un poco más completo

    Vamos a hacer un programa que muestre una pequeña ficha del alumno:

    public class FichaAlumno {

    public static void main(String[] args) {
    System.out.println("===== FICHA DEL ALUMNO =====");
    System.out.println("Nombre: Antonio");
    System.out.println("Curso: Programación con Java");
    System.out.println("Editor: Eclipse");
    System.out.println("Lenguaje: Java");
    System.out.println("============================");
    }

    }

    Salida:

    ===== FICHA DEL ALUMNO =====
    Nombre: Antonio
    Curso: Programación con Java
    Editor: Eclipse
    Lenguaje: Java
    ============================

    Este ejemplo sigue siendo muy básico, pero ya nos permite practicar la escritura de instrucciones, el uso de textos y la ejecución de programas.


    7. Compilar, ejecutar y corregir errores básicos

    Qué significa compilar

    Compilar es transformar el código fuente que hemos escrito en un formato que pueda ejecutar la máquina virtual de Java.

    El archivo que escribimos nosotros tiene extensión:

    .java

    Por ejemplo:

    HolaMundo.java

    Al compilarlo, Java genera un archivo con extensión:

    .class

    Por ejemplo:

    HolaMundo.class

    Ese archivo .class contiene bytecode, que será ejecutado por la JVM.

    En Eclipse, normalmente no tenemos que compilar manualmente. Eclipse compila automáticamente cada vez que guardamos el archivo, siempre que la opción de construcción automática esté activada.

    Podemos comprobarlo en:

    Project > Build Automatically

    Lo normal es dejar esta opción activada.


    Ejecutar un programa en Eclipse

    Para ejecutar un programa Java en Eclipse, abrimos la clase que contiene el método main.

    Después podemos pulsar el botón verde de ejecutar, con forma de play.

    También podemos hacer clic derecho sobre el archivo y elegir:

    Run As > Java Application

    Si todo está correcto, la salida aparecerá en la pestaña Console.

    Por ejemplo, si ejecutamos:

    public class HolaMundo {

    public static void main(String[] args) {
    System.out.println("Hola Mundo");
    }

    }

    Veremos:

    Hola Mundo

    Ejecutar desde consola

    Aunque durante el curso trabajaremos principalmente con Eclipse, conviene entender cómo se ejecutaría un programa desde consola.

    Supongamos que tenemos este archivo:

    HolaMundo.java

    Con este contenido:

    public class HolaMundo {

    public static void main(String[] args) {
    System.out.println("Hola Mundo desde consola");
    }

    }

    Para compilarlo desde terminal:

    javac HolaMundo.java

    Si no hay errores, se generará:

    HolaMundo.class

    Para ejecutarlo:

    java HolaMundo

    Importante: al ejecutar no escribimos .class.

    Correcto:

    java HolaMundo

    Incorrecto:

    java HolaMundo.class

    La salida será:

    Hola Mundo desde consola

    8. Errores básicos al empezar con Java

    Cuando empezamos a programar, los errores son normales. No significan que lo estemos haciendo mal. Significan que estamos aprendiendo a comunicarnos con el lenguaje.

    Lo importante es aprender a leer el error, localizar la línea y corregirlo con calma.


    Error 1: olvidar el punto y coma

    Código incorrecto:

    public class HolaMundo {

    public static void main(String[] args) {
    System.out.println("Hola Mundo")
    }

    }

    El problema está aquí:

    System.out.println("Hola Mundo")

    Falta el punto y coma al final.

    Código correcto:

    public class HolaMundo {

    public static void main(String[] args) {
    System.out.println("Hola Mundo");
    }

    }

    En Java, muchas instrucciones terminan con ;. Si falta, Eclipse marcará un error de sintaxis.


    Error 2: escribir mal System

    Código incorrecto:

    public class HolaMundo {

    public static void main(String[] args) {
    system.out.println("Hola Mundo");
    }

    }

    El problema es que hemos escrito system con minúscula.

    En Java se distinguen mayúsculas y minúsculas. No es lo mismo:

    System

    Que:

    system

    Código correcto:

    public class HolaMundo {

    public static void main(String[] args) {
    System.out.println("Hola Mundo");
    }

    }

    Este concepto se llama case sensitive. Java diferencia entre mayúsculas y minúsculas en nombres de clases, variables, métodos y palabras del lenguaje.


    Error 3: olvidar las comillas en un texto

    Código incorrecto:

    public class HolaMundo {

    public static void main(String[] args) {
    System.out.println(Hola Mundo);
    }

    }

    El texto debe ir entre comillas dobles.

    Código correcto:

    public class HolaMundo {

    public static void main(String[] args) {
    System.out.println("Hola Mundo");
    }

    }

    Cuando escribimos texto literal, usamos comillas dobles:

    "Hola Mundo"

    Error 4: nombre de clase y archivo diferentes

    Supongamos que el archivo se llama:

    HolaMundo.java

    Pero dentro escribimos:

    public class PrimerPrograma {

    public static void main(String[] args) {
    System.out.println("Hola Mundo");
    }

    }

    Esto dará error porque la clase pública se llama PrimerPrograma, pero el archivo se llama HolaMundo.java.

    En Java, si una clase es pública, el archivo debe llamarse igual.

    Solución 1: cambiar el nombre de la clase:

    public class HolaMundo {

    public static void main(String[] args) {
    System.out.println("Hola Mundo");
    }

    }

    Solución 2: cambiar el nombre del archivo a:

    PrimerPrograma.java

    Error 5: borrar una llave

    Código incorrecto:

    public class HolaMundo {

    public static void main(String[] args) {
    System.out.println("Hola Mundo");

    }

    Falta una llave de cierre. Tenemos una llave para abrir la clase y otra para abrir el método main, pero solo una llave de cierre.

    Código correcto:

    public class HolaMundo {

    public static void main(String[] args) {
    System.out.println("Hola Mundo");
    }

    }

    Una buena costumbre es escribir las llaves de forma ordenada y tabular bien el código. Eclipse puede ayudarnos con el formateo automático.

    Podemos usar:

    Source > Format

    O el atajo habitual:

    Ctrl + Shift + F

    En macOS puede variar según la configuración del teclado.


    Error 6: ejecutar la clase equivocada

    A veces tenemos varias clases en el proyecto y ejecutamos una clase que no es la que queremos probar.

    Por ejemplo, tenemos:

    HolaMundo.java
    FichaAlumno.java
    Prueba.java

    Si estamos editando FichaAlumno.java, pero Eclipse ejecuta HolaMundo.java, veremos una salida que no corresponde con el código que acabamos de cambiar.

    Para evitarlo, hacemos clic derecho sobre la clase que queremos ejecutar:

    Run As > Java Application

    Así nos aseguramos de ejecutar el archivo correcto.


    Error 7: no tener método main

    Código:

    public class HolaMundo {

    System.out.println("Hola Mundo");

    }

    Este código es incorrecto porque la instrucción está directamente dentro de la clase, pero no dentro del método main.

    Código correcto:

    public class HolaMundo {

    public static void main(String[] args) {
    System.out.println("Hola Mundo");
    }

    }

    En estos primeros programas, las instrucciones deben estar dentro del método main.


    9. Ejercicios propuestos

    Ejercicio 1: primer mensaje

    Crea un proyecto llamado:

    EjerciciosPrimerosPasos

    Dentro del proyecto, crea una clase llamada:

    Ejercicio01

    El programa debe mostrar por pantalla:

    Estoy aprendiendo Java con Eclipse

    Solución orientativa:

    public class Ejercicio01 {

    public static void main(String[] args) {
    System.out.println("Estoy aprendiendo Java con Eclipse");
    }

    }

    Ejercicio 2: ficha personal

    Crea una clase llamada:

    Ejercicio02

    El programa debe mostrar una ficha con tu nombre, curso y lenguaje que estás aprendiendo.

    Ejemplo de salida:

    Nombre: Laura
    Curso: Programación
    Lenguaje: Java
    Editor: Eclipse

    Solución orientativa:

    public class Ejercicio02 {

    public static void main(String[] args) {
    System.out.println("Nombre: Laura");
    System.out.println("Curso: Programación");
    System.out.println("Lenguaje: Java");
    System.out.println("Editor: Eclipse");
    }

    }

    Ejercicio 3: cartel con líneas

    Crea una clase llamada:

    Ejercicio03

    El programa debe mostrar:

    *************************
    * HOLA JAVA *
    *************************

    Solución orientativa:

    public class Ejercicio03 {

    public static void main(String[] args) {
    System.out.println("*************************");
    System.out.println("* HOLA JAVA *");
    System.out.println("*************************");
    }

    }

    Ejercicio 4: diferencia entre print y println

    Crea una clase llamada:

    Ejercicio04

    Prueba este código:

    public class Ejercicio04 {

    public static void main(String[] args) {
    System.out.print("Hola ");
    System.out.print("Java");
    System.out.println();
    System.out.println("Fin del programa");
    }

    }

    Salida esperada:

    Hola Java
    Fin del programa

    Observa que print no cambia de línea, mientras que println sí lo hace.


    Ejercicio 5: provocando errores

    Crea una clase llamada:

    Ejercicio05

    Escribe el programa Hola Mundo, pero provoca intencionadamente estos errores de uno en uno:

    Quita el punto y coma.

    Cambia System por system.

    Quita una comilla.

    Borra una llave.

    Cambia el nombre de la clase.

    Después observa qué error muestra Eclipse y corrígelo.

    Este ejercicio es importante porque ayuda a perder el miedo a los errores. Un programador no es alguien que nunca se equivoca. Un programador es alguien que aprende a leer, entender y corregir errores.


    10. Resumen del tema

    En este tema hemos preparado el entorno básico para empezar a programar con Java. Hemos instalado el JDK, que contiene las herramientas necesarias para compilar y ejecutar programas Java. También hemos instalado Eclipse, que será nuestro entorno de desarrollo durante el curso.

    Después hemos configurado el workspace, revisado el JDK dentro de Eclipse, activado opciones útiles como la codificación UTF-8 y los números de línea, y hemos creado nuestro primer proyecto Java.

    También hemos visto la estructura mínima de un programa Java: una clase, el método main y una o varias instrucciones. Con el programa Hola Mundo hemos comprobado que todo funciona correctamente.

    Por último, hemos repasado errores básicos muy habituales: olvidar el punto y coma, escribir mal las mayúsculas, borrar llaves, no poner comillas o ejecutar la clase equivocada.

    A partir de aquí ya podemos empezar a trabajar con los primeros conceptos de programación: variables, tipos de datos, operadores, entrada de datos y estructuras de control.

  • 1.1 – Desarrollo Web con PHP: de cero a aplicaciones avanzadas con MySQL, JavaScript, APIs y Laravel 🎧

    1.1 – Desarrollo Web con PHP: de cero a aplicaciones avanzadas con MySQL, JavaScript, APIs y Laravel 🎧

    🎧 Audio de la lección

    En el siguiente audio generado por IA podrás escuchar un texto de introducción al curso y resumen del contexto por el que vamos a empezar nuestro curso.

    El desarrollo de aplicaciones web es una de las áreas más importantes dentro del mundo de la programación. Gran parte de los servicios que utilizamos a diario, como tiendas online, plataformas educativas, paneles de administración, sistemas de reservas, redes sociales o aplicaciones internas de empresa, funcionan sobre tecnologías web conectadas a bases de datos y servidores.

    Este módilo está diseñado para aprender a crear aplicaciones web con PHP desde cero, empezando por los fundamentos del lenguaje y avanzando progresivamente hacia el desarrollo de proyectos completos, organizados, seguros y preparados para un entorno profesional.

    A lo largo del viaje, el alumno aprenderá no solo a escribir código PHP, sino también a comprender cómo funciona una aplicación web real: cómo se reciben datos desde formularios, cómo se validan, cómo se almacenan en una base de datos, cómo se organiza el código mediante programación orientada a objetos, cómo se estructura una aplicación usando patrones como MVC y cómo se añaden funcionalidades modernas mediante JavaScript, AJAX, APIs y frameworks como Laravel.

    El objetivo principal es que el alumno pase de crear pequeños scripts a desarrollar aplicaciones completas, con usuarios, sesiones, permisos, paneles de administración, conexión a bases de datos, seguridad, despliegue en servidor y buenas prácticas de mantenimiento.

    El temario tendrá un enfoque eminentemente práctico. Cada bloque estará orientado a construir conocimiento paso a paso, combinando teoría, ejemplos guiados y proyectos reales. La idea no es memorizar instrucciones, sino entender cómo se diseña, se programa y se despliega una aplicación web desde el inicio hasta su puesta en producción.

    Al finalizar el módulo, el alumno tendrá una visión completa del desarrollo web con PHP y será capaz de crear sus propias aplicaciones, mantener proyectos existentes y continuar aprendiendo tecnologías más avanzadas dentro del ecosistema PHP moderno.

    Programa del módulo

    Bloque 1 — Fundamentos de programación y entorno

    1. Introducción al desarrollo web con PHP
    2. Instalación del entorno de trabajo
    3. Servidores web: Apache, Nginx y PHP integrado
    4. Primeros scripts en PHP
    5. Sintaxis básica de PHP
    6. Variables, tipos de datos y operadores
    7. Estructuras de control
    8. Bucles y control de flujo
    9. Funciones en PHP
    10. Organización básica de archivos en un proyecto PHP

    Bloque 2 — PHP aplicado a la web

    1. Funcionamiento de HTTP
    2. Formularios HTML y procesamiento con PHP
    3. Métodos GET y POST
    4. Validación de datos del usuario
    5. Sanitización y filtrado de entradas
    6. Manejo de errores y mensajes al usuario
    7. Redirecciones y cabeceras HTTP
    8. Inclusión de archivos y plantillas básicas
    9. Gestión de rutas simples
    10. Buenas prácticas iniciales en aplicaciones PHP

    Bloque 3 — Programación orientada a objetos en PHP

    1. Introducción a la programación orientada a objetos
    2. Clases y objetos
    3. Propiedades y métodos
    4. Constructores y destructores
    5. Encapsulación
    6. Modificadores de acceso
    7. Métodos estáticos
    8. Constantes de clase
    9. Herencia
    10. Sobrescritura de métodos
    11. Interfaces
    12. Clases abstractas
    13. Polimorfismo
    14. Traits
    15. Namespaces
    16. Autoloading de clases
    17. Organización de clases en un proyecto
    18. Buenas prácticas de POO en PHP

    Bloque 4 — Bases de datos con MySQL/MariaDB

    1. Introducción a bases de datos relacionales
    2. Diseño básico de bases de datos
    3. Entidades, atributos y relaciones
    4. Claves primarias y claves foráneas
    5. Normalización básica
    6. SQL esencial para aplicaciones web
    7. Consultas SELECT
    8. Inserción de datos
    9. Actualización de registros
    10. Eliminación de registros
    11. Conexión de PHP con MySQL
    12. MySQLi frente a PDO
    13. Consultas preparadas
    14. Control de errores en operaciones de base de datos

    Bloque 5 — JavaScript, AJAX y PHP

    1. Introducción a JavaScript para aplicaciones PHP
    2. Manipulación básica del DOM
    3. Eventos en JavaScript
    4. Validación básica de formularios en cliente
    5. Fetch API
    6. Envío de datos asíncronos
    7. Respuestas JSON desde PHP
    8. Formularios sin recargar la página
    9. Buscadores dinámicos
    10. Validación combinada cliente-servidor
    11. Tablas dinámicas
    12. Gestión de errores en AJAX
    13. Integración PHP, JavaScript y base de datos

    Bloque 6 — Proyecto CRUD básico

    1. Estructura de un CRUD en PHP
    2. Listado de registros
    3. Creación de registros
    4. Edición de registros
    5. Eliminación de registros
    6. Validaciones en un CRUD
    7. Mensajes de confirmación y error
    8. Paginación de resultados
    9. Búsqueda y filtrado
    10. Organización del código del CRUD con clases
    11. Mejora del CRUD con JavaScript y Fetch

    Bloque 7 — Arquitectura de aplicaciones PHP

    1. Separación de responsabilidades
    2. Patrón MVC
    3. Controladores
    4. Modelos
    5. Vistas
    6. Sistema básico de rutas
    7. Controlador frontal
    8. Plantillas reutilizables
    9. Configuración centralizada
    10. Organización profesional de carpetas

    Bloque 8 — Sesiones, usuarios y autenticación

    1. Cookies en PHP
    2. Sesiones en PHP
    3. Registro de usuarios
    4. Inicio de sesión
    5. Cierre de sesión
    6. Protección de páginas privadas
    7. Roles y permisos
    8. Hash seguro de contraseñas
    9. Recordar usuario de forma segura
    10. Recuperación de contraseña

    Bloque 9 — Seguridad en aplicaciones PHP

    1. Principales riesgos de seguridad web
    2. Inyección SQL
    3. Cross-Site Scripting
    4. Cross-Site Request Forgery
    5. Gestión segura de sesiones
    6. Validación avanzada de entradas
    7. Subida segura de archivos
    8. Control de acceso
    9. Protección de credenciales y configuración
    10. Buenas prácticas OWASP aplicadas a PHP

    Bloque 10 — Trabajo con archivos y recursos externos

    1. Subida de archivos
    2. Gestión de imágenes
    3. Lectura y escritura de archivos
    4. Exportación de datos a CSV
    5. Importación de datos desde CSV
    6. Generación de documentos PDF
    7. Envío de correos desde PHP
    8. Consumo de APIs externas
    9. Procesamiento de JSON
    10. Integración con servicios de terceros

    Bloque 11 — Composer y ecosistema PHP moderno

    1. Introducción a Composer
    2. Gestión de dependencias
    3. Autoload con Composer
    4. Uso de librerías externas
    5. Variables de entorno
    6. Estructura moderna de proyectos PHP
    7. Estándares PSR
    8. Herramientas de calidad de código
    9. Logging en aplicaciones PHP
    10. Configuración por entornos

    Bloque 12 — APIs REST con PHP

    1. Introducción a las APIs REST
    2. Diseño de endpoints
    3. Métodos HTTP en APIs
    4. Respuestas JSON estructuradas
    5. Códigos de estado HTTP
    6. Autenticación en APIs
    7. Tokens y JWT
    8. Validación de peticiones API
    9. Documentación de APIs
    10. Consumo de la API desde frontend

    Bloque 13 — Frameworks PHP

    1. Introducción a los frameworks PHP
    2. Instalación de Laravel
    3. Estructura de un proyecto Laravel
    4. Rutas en Laravel
    5. Controladores en Laravel
    6. Vistas con Blade
    7. Modelos y Eloquent ORM
    8. Migraciones y seeders
    9. Validaciones en Laravel
    10. Middleware y autenticación

    Bloque 14 — Laravel avanzado

    1. Relaciones entre modelos
    2. Formularios avanzados
    3. Subida de archivos en Laravel
    4. Autorización con policies y gates
    5. Jobs y colas
    6. Eventos y listeners
    7. Notificaciones
    8. APIs REST con Laravel
    9. Testing en Laravel
    10. Optimización de aplicaciones Laravel

    Bloque 15 — Testing, calidad y mantenimiento

    1. Introducción al testing
    2. Tests unitarios
    3. Tests de integración
    4. PHPUnit
    5. Pruebas de controladores
    6. Pruebas de base de datos
    7. Análisis estático de código
    8. Refactorización
    9. Documentación técnica
    10. Mantenimiento de aplicaciones PHP

    Bloque 16 — Despliegue y administración

    1. Preparación de una aplicación para producción
    2. Configuración de Apache/Nginx
    3. Despliegue en servidor Linux
    4. Permisos y estructura en producción
    5. Gestión de variables de entorno
    6. Certificados HTTPS
    7. Copias de seguridad
    8. Monitorización básica
    9. Logs y diagnóstico de errores
    10. Actualización segura de aplicaciones

    Bloque 17 — Docker, CI/CD y entorno profesional

    1. Introducción a Docker para PHP
    2. Contenedores para Apache/PHP
    3. Contenedores para MySQL/MariaDB
    4. Docker Compose para proyectos PHP
    5. Entornos de desarrollo reproducibles
    6. Git y flujo de trabajo profesional
    7. GitHub/GitLab para proyectos PHP
    8. Integración continua
    9. Despliegue continuo
    10. Automatización de pruebas y análisis

    Bloque 18 — Proyecto final de máster

    1. Análisis de requisitos
    2. Diseño de base de datos
    3. Diseño de arquitectura
    4. Desarrollo del backend
    5. Desarrollo del frontend
    6. Sistema de usuarios y permisos
    7. Panel de administración
    8. API REST del proyecto
    9. Seguridad y pruebas
    10. Despliegue final y documentación del proyecto
  • 1.2 – ¿Qué es PHP?

    1.2 – ¿Qué es PHP?

    PHP es un lenguaje de programación pensado principalmente para crear páginas web dinámicas y aplicaciones web del lado del servidor.

    Cuando un usuario entra en una web, normalmente el navegador recibe HTML, CSS y JavaScript. Pero antes de que eso llegue al navegador, muchas veces hay un servidor que tiene que hacer tareas como:

    • consultar una base de datos;
    • comprobar si el usuario ha iniciado sesión;
    • guardar formularios;
    • cargar productos;
    • gestionar reservas;
    • mostrar contenido diferente según el usuario;
    • generar páginas dinámicas.

    Ahí es donde entra PHP.

    PHP se ejecuta en el servidor, genera una respuesta —normalmente HTML— y se la envía al navegador del usuario.

    Ejemplo sencillo:

    <?php
    $nombre = "Antonio";
    echo "<h1>Hola, $nombre</h1>";
    ?>

    El usuario no ve el código PHP. Solo ve el resultado:

    <h1>Hola, Antonio</h1>

    ¿Por qué PHP sigue siendo importante?

    PHP no es “el lenguaje moderno o de moda”, pero sigue siendo uno de los lenguajes más importantes de la web real. Según W3Techs, PHP se usa en aproximadamente el 71,2% de las webs cuyo lenguaje de servidor es conocido, muy por encima de otros lenguajes de servidor como Ruby, JavaScript, Java o ASP.NET.

    Además, PHP sigue evolucionando. Actualmente las versiones mantenidas oficialmente incluyen PHP 8.4 y PHP 8.5, con soporte activo y de seguridad definido por el propio proyecto PHP.

    Ideas clave

    IdeaExplicación sencilla
    PHP se usa en servidoresNo se ejecuta normalmente en el navegador, sino en el servidor web.
    PHP genera HTML dinámicoPuede crear páginas diferentes según datos, usuarios o formularios.
    PHP trabaja muy bien con bases de datosEs muy habitual usarlo con MySQL o MariaDB.
    PHP está muy presente en hosting realMuchos alojamientos web baratos o compartidos soportan PHP por defecto.
    PHP mueve proyectos enormesWordPress, Drupal, Moodle, MediaWiki, Magento y muchos CMS/plataformas usan PHP.
    PHP tiene mucha salida prácticaPermite crear webs, paneles de administración, tiendas online, APIs y aplicaciones internas.

    Comparativa rápida: PHP frente a otros lenguajes web

    LenguajeUso principalDónde se ejecuta normalmenteDificultad inicialVentajasInconvenientes
    PHPDesarrollo web backendServidorBaja / mediaFácil de empezar, mucho hosting compatible, ideal con MySQL, enorme ecosistema webHay mucho código antiguo mal escrito; requiere buenas prácticas desde el principio
    JavaScriptFrontend y backend con Node.jsNavegador y servidorBaja / mediaImprescindible en frontend, muy versátil, sirve para web completaEl ecosistema cambia muy rápido; puede ser caótico al principio
    PythonScripts, IA, automatización, backendServidor / escritorioBajaMuy legible, ideal para aprender, potente en datos e IAEn hosting web tradicional no siempre es tan directo como PHP
    JavaAplicaciones empresariales, backend robustoServidor / JVMMedia / altaMuy usado en empresas, fuerte tipado, escalableMás verboso, curva inicial mayor
    C#Aplicaciones Windows, backend con .NET, videojuegos con UnityServidor / escritorio / UnityMediaMuy potente, moderno, buen entorno con Visual StudioMenos habitual en hosting compartido clásico
    RubyBackend web con Ruby on RailsServidorMediaMuy productivo, elegante, Rails fue muy influyenteMenor presencia actual que PHP, JavaScript o Python
    GoServicios backend, APIs, sistemasServidorMediaMuy rápido, simple, ideal para microserviciosMenos orientado a principiantes web que PHP
    TypeScriptJavaScript con tiposNavegador y servidorMediaMás ordenado que JavaScript, muy usado en proyectos modernosAñade complejidad inicial

    Comparativa: PHP, JavaScript y Python para aprender desarrollo web

    AspectoPHPJavaScriptPython
    ¿Sirve para crear páginas web dinámicas?SíSíSí
    ¿Se usa en el navegador?No, normalmenteSí, es el lenguaje principal del navegadorNo, normalmente
    ¿Se usa en el servidor?SíSí, con Node.jsSí, con frameworks como Django o Flask
    ¿Es fácil hacer una web básica?Muy fácilFácil, pero necesita más piezas si usamos backendFácil, pero depende del framework
    ¿Funciona bien con MySQL?Muy bienBienBien
    ¿Lo soportan muchos hostings baratos?Sí, muchísimoDependeDepende
    ¿Tiene CMS famosos?Sí: WordPress, Drupal, Joomla, MoodleMenos en el sentido clásicoMenos en el sentido clásico
    ¿Es buena primera opción para backend web clásico?SíSí, si ya se domina JSSí, si se quiere ir hacia datos, IA o Django

    Comparativa: PHP puro, WordPress y Laravel

    OpciónQué esCuándo usarloVentajasLimitaciones
    PHP puroProgramar directamente con PHP sin frameworkPara aprender fundamentos, formularios, sesiones, CRUD, conexión a BDSe entiende cómo funciona todo por dentroEn proyectos grandes puede volverse desordenado si no se estructura bien
    WordPressCMS hecho en PHPBlogs, webs corporativas, academias, tiendas pequeñas/mediasRápido de montar, muchos temas/plugins, muy usado profesionalmenteNo siempre es ideal para aplicaciones muy personalizadas
    LaravelFramework moderno de PHPAplicaciones web profesionales, APIs, paneles, SaaSEstructura clara, MVC, migraciones, rutas, seguridad, comunidad fuerteRequiere conocer antes bien PHP y POO
    SymfonyFramework PHP muy robustoProyectos empresariales, aplicaciones grandes, componentes reutilizablesMuy profesional, modular, usado por otros proyectos como DrupalCurva de aprendizaje más alta
    DrupalCMS avanzado en PHPPortales complejos, instituciones, webs con mucha estructura de contenidoMuy flexible y potenteMás complejo que WordPress
    MoodlePlataforma educativa en PHPAulas virtuales, cursos online, LMSMuy usado en educaciónPersonalizarlo requiere conocimientos técnicos

    Aplicaciones actuales hechas con PHP o basadas en PHP

    Aplicación / plataformaTipoRelación con PHPUso habitual
    WordPressCMSEstá desarrollado en PHP y sigue requiriendo PHP para funcionar. WordPress recomienda usar versiones modernas de PHP por seguridad y rendimiento.Blogs, webs corporativas, medios digitales, tiendas con WooCommerce
    WooCommercePlugin de e-commerce para WordPressFunciona sobre WordPress, por tanto depende de PHPTiendas online pequeñas y medianas
    DrupalCMS avanzadoEs un CMS PHP y usa componentes de Symfony.Portales institucionales, universidades, administraciones, webs grandes
    Joomla!CMSProyecto PHP que también usa componentes del ecosistema Symfony.Webs corporativas, comunidades, portales
    MediaWikiMotor wikiMediaWiki indica que PHP es el lenguaje en el que está escrito y que es necesario para ejecutarlo.Wikis, documentación, bases de conocimiento; Wikipedia usa MediaWiki
    MoodleLMS / plataforma educativaMoodle se define como una aplicación PHP respaldada por base de datos relacional.Aulas virtuales, formación online, centros educativos
    Magento / Adobe CommerceComercio electrónicoAdobe Commerce/Magento requiere PHP y extensiones PHP concretas para funcionar.Tiendas online grandes, catálogos complejos
    PrestaShopComercio electrónicoPlataforma de e-commerce desarrollada en PHPTiendas online pequeñas y medianas
    LaravelFramework PHPFramework PHP para crear aplicaciones web modernasAplicaciones a medida, APIs, paneles de gestión
    SymfonyFramework PHPFramework PHP de alto rendimiento para aplicaciones escalables.Proyectos empresariales, componentes reutilizables, backend profesional
    MatomoAnalítica webAplicación open source escrita en PHPAlternativa a Google Analytics instalada en servidor propio
    phpMyAdminAdministración de bases de datosAplicación PHP para gestionar MySQL/MariaDB desde navegadorGestión de bases de datos en hosting, servidores y laboratorios

    Tabla: ¿Para qué se usa PHP en la vida real?

    Caso de usoEjemplo práctico
    Webs corporativasUna empresa necesita una web editable con panel de administración.
    Blogs y medios digitalesUn periódico, blog o revista online publica contenido todos los días.
    Tiendas onlineCatálogo de productos, carrito, pagos, usuarios y pedidos.
    Aplicaciones internasPanel para gestionar alumnos, reservas, incidencias o inventario.
    Formularios webContacto, inscripción, encuestas, solicitudes.
    APIs sencillasUn frontend pide datos a un backend PHP en formato JSON.
    Plataformas educativasMoodle, campus virtuales, actividades, usuarios y calificaciones.
    Wikis y documentaciónMediaWiki para documentación colaborativa.
    Plugins y temasDesarrollo de extensiones para WordPress, WooCommerce o Moodle.

    Comparativa de PHP según tipo de proyecto

    Proyecto¿PHP es buena opción?Motivo
    Blog personalSíWordPress lo resuelve muy bien.
    Web corporativaSíRápido, económico y fácil de alojar.
    Tienda online pequeñaSíWooCommerce o PrestaShop son opciones habituales.
    Tienda online grandeSí, con cuidadoMagento/Adobe Commerce es potente, pero requiere buena infraestructura.
    Aplicación CRUD de gestiónSíPHP con Laravel o Symfony encaja muy bien.
    API RESTSíLaravel, Symfony o Slim permiten crear APIs profesionales.
    Aplicación de IANo como primera opciónPython suele ser mejor para IA, aunque PHP puede consumir APIs de IA.
    VideojuegosNoMejor C#, C++, JavaScript o motores como Unity/Unreal.
    Aplicación móvil nativaNo directamentePHP puede servir como backend, pero no como app móvil nativa.
    Panel de administraciónSíEs uno de sus usos más habituales.

    PHP no es importante porque sea “el lenguaje más moderno” o “el más elegante”. PHP es importante porque resuelve problemas reales de la web y porque sigue estando instalado en millones de servidores.

    Aprender PHP permite entender muy bien cómo funciona una aplicación web clásica:

    ConceptoQué aprenderán con PHP
    Cliente-servidorEl navegador pide una página y el servidor responde.
    FormulariosEl usuario envía datos al servidor.
    Bases de datosPHP consulta, guarda, modifica y borra información.
    SesionesEl servidor recuerda qué usuario ha iniciado sesión.
    SeguridadValidación, contraseñas, permisos, SQL injection, XSS.
    ArquitecturaSeparar lógica, vistas, modelos, controladores y configuración.
    DespliegueSubir una aplicación a un hosting o servidor real.

    :

    “PHP es uno de los lenguajes que más ha construido la web que usamos cada día. Aunque hoy existen muchas alternativas, PHP sigue siendo fundamental porque está detrás de herramientas enormes como WordPress, Moodle, Drupal, MediaWiki o Magento. Aprender PHP nos permite entender cómo funciona una aplicación web desde dentro: cómo se reciben datos, cómo se conecta con una base de datos, cómo se gestionan usuarios y cómo se genera una página dinámica. No vamos a aprender PHP solo para escribir código, sino para entender cómo se construye una web real.”

    PHP y empleo

    PHP tiene salida laboral porque hay muchísimas webs, tiendas online, CMS, plataformas educativas y aplicaciones empresariales creadas con PHP. No todo el trabajo consiste en crear proyectos nuevos desde cero; una parte muy grande del empleo tecnológico consiste en mantener, mejorar, migrar y ampliar sistemas que ya existen.


    Tabla: salidas laborales relacionadas con PHP

    Perfil profesionalQué haceTecnologías habituales
    Desarrollador PHP JuniorCrea funcionalidades básicas, corrige errores, trabaja con formularios, bases de datos y paneles webPHP, MySQL, HTML, CSS, JavaScript
    Desarrollador WordPressCrea webs, personaliza temas, instala y adapta plugins, optimiza rendimientoWordPress, PHP, MySQL, CSS, JavaScript
    Desarrollador LaravelCrea aplicaciones web modernas, APIs, paneles de gestión y sistemas CRUDPHP, Laravel, MySQL, Composer, Git
    Desarrollador SymfonyTrabaja en aplicaciones más estructuradas o empresarialesPHP, Symfony, Doctrine, Twig, APIs
    Desarrollador Full Stack PHPTrabaja tanto en backend como en frontendPHP, Laravel/Symfony, JavaScript, Vue/React, MySQL
    Técnico web / WebmasterMantiene webs, hosting, dominios, CMS, seguridad básica y contenidosWordPress, PHP, hosting, FTP/SFTP, bases de datos
    Desarrollador e-commerceCrea y mantiene tiendas onlineWooCommerce, PrestaShop, Magento, PHP, pasarelas de pago
    Mantenimiento de aplicaciones legacyActualiza sistemas antiguos, corrige errores y migra códigoPHP antiguo, MySQL, jQuery, Bootstrap, Git
    Backend Developer PHPCrea lógica de servidor, APIs, autenticación y conexión con bases de datosPHP, Laravel/Symfony, SQL, REST APIs

    Tabla: tecnologías que suelen acompañar a PHP en ofertas de empleo

    TecnologíaPor qué es importante
    HTMLPHP suele generar páginas web, así que hay que entender la estructura.
    CSSNecesario para maquetar y adaptar interfaces.
    JavaScriptImprescindible para añadir interacción en el navegador.
    MySQL / MariaDBEs la base de datos más habitual junto a PHP.
    Git / GitHub / GitLabCasi cualquier empresa lo usa para controlar versiones.
    ComposerGestor de dependencias de PHP. Muy importante en proyectos modernos.
    LaravelUno de los frameworks PHP más demandados.
    SymfonyMuy usado en proyectos profesionales y empresariales.
    WordPressMuy importante para empleo en agencias, marketing, diseño web y mantenimiento.
    DockerCada vez más habitual para entornos de desarrollo y despliegue.
    APIs RESTMuchas aplicaciones PHP comunican frontend, móviles o servicios externos mediante APIs.
    Linux básicoMuchos servidores PHP funcionan sobre Linux.
    Seguridad webValidación, sesiones, contraseñas, SQL injection, XSS, permisos.

    Comparativa laboral: PHP frente a otros lenguajes

    LenguajeMercado laboralTipo de empleo habitualComentario realista
    PHPMuy Alto en web, CMS, e-commerce y mantenimientoWordPress, Laravel, Symfony, tiendas online, aplicaciones internasMuy práctico para entrar en desarrollo web y trabajar con proyectos reales.
    JavaScriptMuy altoFrontend, backend con Node.js, full stackImprescindible para web moderna. Conviene aprenderlo junto a PHP.
    PythonMuy altoAutomatización, datos, IA, backend, scriptingExcelente lenguaje, pero menos ligado al hosting web clásico que PHP.
    JavaAltoBackend empresarial, banca, grandes sistemasMuy potente, pero con curva de entrada mayor.
    C#Alto.NET, escritorio, backend, UnityMuy buena opción para empresa y videojuegos.
    RubyMás limitadoProyectos Rails, startups, mantenimientoMenos demanda general que hace años.
    GoCrecienteBackend, microservicios, cloudMuy interesante, pero normalmente no es el primer lenguaje para empezar web.

    Tabla: tipos de empresa donde se usa PHP

    Tipo de empresaUso habitual de PHP
    Agencias webWordPress, WooCommerce, webs corporativas, landing pages.
    Empresas de marketing digitalWebs de clientes, campañas, formularios, SEO técnico.
    Tiendas onlineWooCommerce, PrestaShop, Magento, integraciones con pagos y envíos.
    Centros educativosMoodle, campus virtuales, plugins, integraciones.
    Medios digitalesWordPress, gestores de noticias, sistemas editoriales.
    Empresas pequeñas y medianasAplicaciones internas, CRM, paneles de gestión, reservas, facturación.
    Consultoras tecnológicasMantenimiento, migraciones, APIs, proyectos con Laravel o Symfony.
    Administraciones e institucionesPortales, Drupal, sistemas de gestión de contenidos.


    Tabla: niveles de empleo con PHP

    NivelQué debería saber
    JuniorPHP básico, formularios, sesiones, MySQL, HTML, CSS, algo de JavaScript, Git.
    Junior avanzadoCRUD completo, login, validación, subida de archivos, estructura MVC básica, seguridad mínima.
    Backend PHPLaravel o Symfony, APIs, autenticación, roles, testing básico, Composer, Docker.
    Full Stack PHPPHP + framework + JavaScript moderno + consumo de APIs + despliegue.
    WordPress DeveloperTemas, plugins, hooks, custom post types, WooCommerce, seguridad y rendimiento.
    Senior PHPArquitectura, patrones, testing, rendimiento, seguridad, escalabilidad, refactorización.


    “PHP sigue teniendo empleo porque una parte enorme de la web funciona con PHP. No solo hablamos de WordPress, también de tiendas online, plataformas educativas, paneles de gestión, APIs y aplicaciones internas de empresas. Ahora bien, aprender PHP no significa memorizar cuatro etiquetas. Para ser empleable hay que aprender a construir aplicaciones completas: formularios, bases de datos, login, seguridad, Git, despliegue y, más adelante, frameworks como Laravel o Symfony.”

  • 1.3 – Arquitectura cliente-servidor con PHP

    1.3 – Arquitectura cliente-servidor con PHP

    Antes de empezar a programar con PHP, es importante entender dónde se ejecuta PHP y qué papel tiene dentro de una aplicación web.

    Cuando entramos en una página web, normalmente participan dos partes:

    ParteQué esEjemplos
    ClienteEl dispositivo o programa que solicita la páginaNavegador web: Chrome, Firefox, Edge, Safari
    ServidorEl equipo que recibe la petición, procesa la información y devuelve una respuestaServidor con Apache, Nginx, PHP, MySQL, etc.

    1. ¿Qué es el cliente?

    El cliente es normalmente el navegador del usuario.

    Por ejemplo, cuando un alumno escribe en el navegador:

    https://miweb.com/index.php

    El navegador está haciendo una petición al servidor donde está alojada esa página.

    El cliente puede interpretar principalmente:

    TecnologíaDónde se ejecutaPara qué sirve
    HTMLEn el navegadorEstructura de la página
    CSSEn el navegadorDiseño y estilos
    JavaScriptEn el navegadorInteractividad

    Por ejemplo, el navegador sí entiende este código:

    <h1>Hola mundo</h1>
    <p>Esta página se muestra en el navegador.</p>

    Pero el navegador no ejecuta PHP directamente.


    2. ¿Qué es el servidor?

    El servidor es el equipo que recibe la petición del cliente y prepara la respuesta.

    En una aplicación PHP, el servidor suele tener instalados varios elementos:

    ElementoFunción
    Apache o NginxServidor web que recibe las peticiones
    PHPLenguaje que procesa la lógica en el servidor
    MySQL/MariaDBBase de datos donde se guarda información
    Sistema operativoLinux, Windows Server, etc.

    Un servidor puede estar en Internet, en una empresa, en un hosting o incluso en nuestro propio ordenador durante las prácticas.

    Por ejemplo, cuando usamos XAMPP, Laragon, MAMP o Docker, estamos creando un pequeño entorno de servidor en local.


    3. ¿Dónde se ejecuta PHP?

    PHP se ejecuta en el servidor, no en el navegador.

    Esto es una idea clave.

    Cuando tenemos un archivo llamado:

    index.php

    y dentro escribimos:

    <?php
    echo "Hola desde PHP";
    ?>

    El navegador no recibe ese código PHP. El servidor primero lo ejecuta y después envía al navegador el resultado convertido en HTML.

    El navegador recibiría algo parecido a esto:

    Hola desde PHP

    Por eso, si inspeccionamos la página desde el navegador, no veremos el código PHP original.


    4. Proceso completo de una petición PHP

    El funcionamiento básico sería este:

    PasoQué ocurre
    1El usuario escribe una dirección en el navegador
    2El navegador envía una petición al servidor
    3Apache o Nginx recibe la petición
    4Si el archivo es PHP, el servidor se lo pasa al intérprete de PHP
    5PHP ejecuta el código
    6Si hace falta, PHP consulta la base de datos
    7PHP genera una respuesta en HTML
    8El servidor envía esa respuesta al navegador
    9El navegador muestra la página al usuario

    Visualmente:


    5. Ejemplo sencillo

    Imaginemos este archivo llamado saludo.php:

    <?php
    $nombre = "Antonio";

    echo "<h1>Bienvenido, $nombre</h1>";
    echo "<p>Esta página ha sido generada por PHP en el servidor.</p>";
    ?>

    El servidor ejecuta el código PHP y genera HTML.

    El navegador recibiría algo así:

    <h1>Bienvenido, Antonio</h1>
    <p>Esta página ha sido generada por PHP en el servidor.</p>

    El navegador solo ve el resultado final, no la lógica interna.


    6. Diferencia entre página estática y página dinámica

    Una página web puede ser estática o dinámica.

    Tipo de páginaCaracterísticasEjemplo
    EstáticaSiempre muestra el mismo contenidoUna página HTML fija
    DinámicaEl contenido puede cambiar según datos, usuarios o formulariosUna tienda online, un login, un blog

    Página estática

    <h1>Bienvenido a mi web</h1>
    <p>Este contenido siempre es el mismo.</p>

    Página dinámica con PHP

    <?php
    $hora = date("H:i");

    echo "<h1>Bienvenido a mi web</h1>";
    echo "<p>La hora actual del servidor es: $hora</p>";
    ?>

    En este caso, el contenido cambia dependiendo del momento en el que se cargue la página.


    7. PHP y la base de datos

    Una de las grandes utilidades de PHP es que puede conectarse a una base de datos.

    Por ejemplo, una aplicación web puede necesitar:

    AcciónQué hace PHP
    Iniciar sesiónComprueba usuario y contraseña
    Mostrar productosConsulta los productos en la base de datos
    Registrar un usuarioGuarda los datos en MySQL
    Hacer una reservaInserta una reserva en la base de datos
    Mostrar noticiasRecupera artículos almacenados

    Ejemplo conceptual:


    8. Ejemplo con formulario

    Un caso muy típico en PHP es trabajar con formularios.

    Archivo formulario.html:

    <form action="procesar.php" method="post">
    <label>Nombre:</label>
    <input type="text" name="nombre">

    <button type="submit">Enviar</button>
    </form>

    Archivo procesar.php:

    <?php
    $nombre = $_POST["nombre"];

    echo "<h1>Hola, $nombre</h1>";
    echo "<p>El formulario ha sido procesado en el servidor.</p>";
    ?>

    El proceso sería:

    PasoQué ocurre
    1El usuario rellena el formulario
    2Pulsa el botón enviar
    3El navegador manda los datos al servidor
    4PHP recibe los datos mediante $_POST
    5PHP genera una respuesta personalizada
    6El navegador muestra el resultado

    9. ¿Por qué esto es importante?

    Entender la arquitectura cliente-servidor nos ayuda a saber qué hace cada tecnología.

    TecnologíaSe ejecuta enFunción principal
    HTMLClienteEstructura
    CSSClienteDiseño
    JavaScriptClienteInteractividad en navegador
    PHPServidorLógica de negocio
    SQLServidor/base de datosConsultar y modificar datos

    Un error común al empezar es pensar que PHP funciona igual que JavaScript. Pero no es así.

    JavaScript normalmente se ejecuta en el navegador.

    PHP se ejecuta en el servidor y genera una respuesta.


    PHP no se ve en el navegador. PHP se ejecuta en el servidor y el navegador recibe el resultado, normalmente en forma de HTML.

    Esta frase resume gran parte del funcionamiento de PHP dentro de una aplicación web.


    11. Ejercicio propuesto

    Crea un archivo llamado arquitectura.php con el siguiente código:

    <?php
    $titulo = "Arquitectura cliente-servidor";
    $lenguaje = "PHP";
    $servidor = $_SERVER["SERVER_SOFTWARE"];

    echo "<h1>$titulo</h1>";
    echo "<p>Esta página ha sido generada usando $lenguaje.</p>";
    echo "<p>El código PHP se ha ejecutado en el servidor.</p>";
    echo "<p>Servidor utilizado: $servidor</p>";
    ?>

    Después responde:

    PreguntaRespuesta
    ¿Dónde se ejecuta el código PHP?
    ¿Qué recibe finalmente el navegador?
    ¿Se puede ver el código PHP desde “Inspeccionar elemento”?
    ¿Qué diferencia hay entre HTML y PHP?
    ¿Qué papel cumple Apache o Nginx?

    La arquitectura cliente-servidor es la base de las aplicaciones web.

    El cliente solicita información mediante el navegador.

    El servidor procesa la petición.

    PHP se ejecuta en el servidor, puede consultar bases de datos y genera una respuesta que normalmente se envía al navegador como HTML.

    Por eso PHP es una pieza fundamental en muchas aplicaciones web dinámicas, como blogs, tiendas online, paneles de administración, sistemas de reservas o plataformas educativas.