Categoría: Programación PHP

  • 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.

  • 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?
    ¿Se usa en el navegador?No, normalmenteSí, es el lenguaje principal del navegadorNo, normalmente
    ¿Se usa en el servidor?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í, 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 personalWordPress lo resuelve muy bien.
    Web corporativaRápido, económico y fácil de alojar.
    Tienda online pequeñaWooCommerce o PrestaShop son opciones habituales.
    Tienda online grandeSí, con cuidadoMagento/Adobe Commerce es potente, pero requiere buena infraestructura.
    Aplicación CRUD de gestiónPHP con Laravel o Symfony encaja muy bien.
    API RESTLaravel, 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ónEs 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.

  • 1.4 – Entorno de trabajo para programar con PHP 🎥

    1.4 – Entorno de trabajo para programar con PHP 🎥

    Antes de empezar a programar con PHP necesitamos preparar un entorno de trabajo. PHP no funciona igual que HTML o CSS, donde podemos abrir directamente el archivo en el navegador. En PHP necesitamos un servidor que interprete el código y devuelva al navegador el resultado generado.

    Cuando escribimos una página en PHP, el navegador no ejecuta directamente ese código. El proceso habitual es el siguiente:

    1. El usuario accede a una dirección desde el navegador.
    2. El navegador hace una petición al servidor web.
    3. El servidor localiza el archivo PHP solicitado.
    4. PHP interpreta el código del archivo.
    5. El servidor devuelve al navegador una página HTML generada.
    6. El navegador muestra el resultado final al usuario.

    Por este motivo, para trabajar cómodamente durante el aprendizaje vamos a utilizar un entorno local. Esto nos permitirá tener en nuestro propio ordenador todo lo necesario para probar nuestras aplicaciones web sin depender de un servidor externo.

    Entornos locales preparados

    Existen herramientas que instalan de forma sencilla los elementos básicos que necesitamos para trabajar con PHP. Algunas de las más conocidas son:

    HerramientaSistemas habitualesIncluye normalmenteUso principal
    XAMPPWindows, Linux y macOSApache, PHP, MariaDB/MySQL y phpMyAdminMuy usado en formación y pruebas locales
    MAMPmacOS y WindowsApache o Nginx, PHP, MySQL y herramientas de gestiónMuy cómodo en equipos Mac
    WAMPWindowsApache, PHP y MySQL/MariaDBAlternativa clásica para Windows
    LaragonWindowsApache/Nginx, PHP, MySQL y otras herramientasEntorno ligero y flexible para desarrollo

    Estas herramientas nos permiten arrancar un servidor web en nuestro propio equipo. De esta forma podremos guardar nuestros archivos PHP en una carpeta concreta del entorno y acceder a ellos desde el navegador usando direcciones como:

    http://localhost/

    o, según la configuración:

    http://localhost/mi_proyecto/

    La palabra localhost hace referencia a nuestro propio ordenador. Es decir, estamos usando nuestro equipo como si fuera un pequeño servidor web local.

    Por qué no usaremos inicialmente las integraciones de los IDE

    Muchos editores e IDEs modernos permiten ejecutar PHP directamente desde sus propias herramientas, extensiones o servidores integrados. Por ejemplo, algunos entornos permiten lanzar un servidor interno, depurar código o conectar directamente con bases de datos.

    Aunque estas opciones son útiles, al principio no las vamos a utilizar como base principal. El motivo es que queremos entender claramente cómo funciona una aplicación PHP en un entorno realista:

    • dónde se colocan los archivos del proyecto;
    • qué papel tiene el servidor web;
    • cómo se comunica el navegador con el servidor;
    • cómo se interpreta el código PHP;
    • cómo se conecta PHP con una base de datos;
    • cómo se accede a una aplicación desde una URL.

    Usar herramientas como XAMPP o MAMP nos ayuda a ver el proceso completo de forma más clara. El IDE será nuestro editor de código, pero no queremos que oculte el funcionamiento real del servidor.

    Por tanto, podremos usar editores como Visual Studio Code, PhpStorm, Eclipse, NetBeans u otros, pero el servidor será externo al IDE. Así entenderemos mejor la arquitectura real de una aplicación web.

    Trabajar directamente en un servidor

    Otra posibilidad es trabajar directamente sobre un servidor remoto. En este caso, los archivos PHP no se ejecutan en nuestro ordenador, sino en una máquina conectada a la red o a Internet.

    Por ejemplo, podríamos tener un servidor con Linux, Apache, PHP y MySQL instalado. Subiríamos nuestros archivos mediante FTP, SFTP, Git o alguna herramienta similar, y probaríamos la aplicación desde el navegador accediendo a la dirección del servidor.

    Este enfoque se parece más a un entorno de producción, pero también tiene algunos inconvenientes para empezar:

    • es más fácil cometer errores que afecten a una aplicación real;
    • dependemos de la conexión con el servidor;
    • la configuración inicial puede ser más compleja;
    • es menos cómodo para hacer pruebas rápidas;
    • puede ser más difícil depurar errores al principio.

    Aun así, es importante conocer esta forma de trabajo, porque muchas aplicaciones PHP se despliegan finalmente en servidores reales.

    Trabajar con contenedores

    Más adelante también podremos trabajar con contenedores, especialmente usando Docker. Esta forma de trabajo permite crear entornos aislados donde cada servicio se ejecuta en su propio contenedor.

    Por ejemplo, una aplicación PHP podría tener varios contenedores:

    ContenedorFunción
    Apache o NginxServidor web
    PHPInterpretación del código PHP
    MySQL o MariaDBBase de datos
    phpMyAdminGestión visual de la base de datos

    La ventaja de los contenedores es que podemos definir todo el entorno en archivos de configuración. Así, cualquier alumno o desarrollador puede levantar el mismo entorno en su equipo con los mismos servicios y versiones.

    En este curso empezaremos usando entornos locales como XAMPP o MAMP porque son más directos para aprender. Más adelante veremos cómo llevar estos conocimientos a entornos más profesionales usando servidores reales y contenedores.

    Idea principal

    Para aprender PHP correctamente no basta con escribir código. También necesitamos entender el entorno donde ese código se ejecuta.

    PHP forma parte de una arquitectura cliente-servidor. El navegador actúa como cliente, el servidor procesa la petición, PHP genera el contenido dinámico y la base de datos almacena la información.

    Por eso, durante las primeras prácticas trabajaremos con un servidor local instalado en nuestro propio ordenador. Esto nos permitirá aprender paso a paso cómo funciona una aplicación web antes de pasar a escenarios más avanzados como servidores remotos o contenedores Docker.

    Instalación de XAMPP

    1. ¿Qué es XAMPP?

    XAMPP es un paquete de software que nos permite instalar de forma sencilla un entorno de servidor web en nuestro propio ordenador.

    Cuando trabajamos con PHP no basta con abrir el archivo directamente en el navegador, como haríamos con un archivo HTML. PHP necesita ser interpretado por un servidor. XAMPP nos proporciona ese entorno de trabajo local para poder practicar y desarrollar aplicaciones web.

    XAMPP incluye normalmente los siguientes componentes:

    ComponenteFunción
    ApacheServidor web que recibe las peticiones del navegador
    PHPLenguaje que interpreta los archivos .php
    MariaDB / MySQLSistema de base de datos
    phpMyAdminHerramienta web para gestionar bases de datos
    PerlOtro lenguaje incluido en el paquete

    En este curso usaremos XAMPP como entorno local para aprender PHP de forma sencilla antes de pasar a entornos más avanzados como servidores reales o contenedores Docker.


    2. Descargar XAMPP

    Para descargar XAMPP debemos acceder a la página oficial:

    https://www.apachefriends.org/es/download.html

    Es recomendable descargar siempre XAMPP desde la página oficial de Apache Friends para evitar instaladores modificados o versiones no fiables.


    3. Instalación de XAMPP en Windows

    3.1. Descargar el instalador

    Desde la página oficial descargamos la versión de XAMPP para Windows.

    El archivo descargado tendrá un nombre parecido a este:

    xampp-windows-x64-8.x.x-installer.exe

    El número de versión puede cambiar dependiendo de la versión disponible en ese momento.


    3.2. Ejecutar el instalador

    Una vez descargado el archivo, hacemos doble clic sobre él para iniciar la instalación.

    Es posible que Windows muestre una advertencia de seguridad o de permisos. En ese caso, aceptamos la ejecución si hemos descargado el archivo desde la página oficial.

    También puede aparecer una advertencia relacionada con el control de cuentas de usuario de Windows. Para evitar problemas de permisos, es recomendable instalar XAMPP directamente en:

    C:\xampp

    No es recomendable instalarlo dentro de Archivos de programa, ya que puede dar problemas de permisos al trabajar con archivos del servidor.


    3.3. Seleccionar componentes

    Durante la instalación aparecerá una pantalla para seleccionar los componentes.

    Para este curso podemos dejar marcados, como mínimo:

    • Apache
    • MySQL o MariaDB
    • PHP
    • phpMyAdmin

    También pueden aparecer otros componentes como Perl, Tomcat, Mercury o FileZilla. Para empezar con PHP no son imprescindibles.


    3.4. Elegir carpeta de instalación

    Seleccionamos como carpeta de instalación:

    C:\xampp

    Esta será la carpeta principal donde se instalará XAMPP.

    Dentro de esta carpeta encontraremos subcarpetas importantes como:

    CarpetaFunción
    apacheArchivos del servidor Apache
    mysqlArchivos relacionados con la base de datos
    phpArchivos del intérprete PHP
    htdocsCarpeta donde colocaremos nuestros proyectos web

    3.5. Finalizar la instalación

    Continuamos con el asistente hasta finalizar.

    Al terminar, podemos marcar la opción para abrir el panel de control de XAMPP.





    6. El panel de control de XAMPP

    Una vez instalado XAMPP, podemos abrir su panel de control.

    Desde este panel podremos iniciar y detener los servicios principales.

    Los servicios que más usaremos al principio son:

    ServicioPara qué sirve
    ApachePermite ejecutar páginas PHP desde el navegador
    MySQL / MariaDBPermite trabajar con bases de datos
    phpMyAdminPermite administrar las bases de datos desde el navegador

    Para trabajar con PHP debemos iniciar como mínimo:

    • Apache

    Si nuestra aplicación usa base de datos, también debemos iniciar:

    • MySQL o MariaDB

    7. Comprobar que XAMPP funciona

    Una vez iniciado Apache, abrimos el navegador y escribimos:

    http://localhost

    Si XAMPP está funcionando correctamente, veremos la página de bienvenida o panel inicial de XAMPP.

    Esto significa que nuestro ordenador ya está funcionando como servidor web local.


    8. Carpeta donde se guardan los proyectos

    La carpeta más importante para empezar es htdocs.

    En Windows suele estar en:

    C:\xampp\htdocs

    En macOS suele estar en:

    /Applications/XAMPP/htdocs

    En Linux suele estar en:

    /opt/lampp/htdocs

    Todo lo que coloquemos dentro de esa carpeta podrá abrirse desde el navegador usando localhost.


    9. Crear nuestro primer proyecto PHP

    Dentro de la carpeta htdocs, creamos una carpeta llamada:

    mi_proyecto

    Dentro de esa carpeta creamos un archivo llamado:

    index.php

    La estructura quedaría así:

    htdocs/
    └── mi_proyecto/
        └── index.php

    Dentro del archivo index.php escribimos:

    <?php
    echo "Hola, estoy ejecutando PHP con XAMPP";
    ?>

    Guardamos el archivo.

    Después abrimos el navegador y escribimos:

    http://localhost/mi_proyecto/index.php

    Si todo está correcto, veremos en pantalla:

    Hola, estoy ejecutando PHP con XAMPP

    10. Probar PHP dentro de HTML

    También podemos mezclar HTML y PHP dentro del mismo archivo.

    Modificamos el archivo index.php con este contenido:

    <!DOCTYPE html>
    <html lang="es">
    <head>
        <meta charset="UTF-8">
        <title>Primera prueba con PHP</title>
    </head>
    <body>
    
        <h1>Mi primera página con PHP</h1>
    
        <p>Este texto está escrito en HTML.</p>
    
        <p>
            <?php
                echo "Este texto ha sido generado por PHP.";
            ?>
        </p>
    
    </body>
    </html>

    Al abrir de nuevo:

    http://localhost/mi_proyecto/index.php

    veremos una página HTML normal, pero parte de su contenido habrá sido generado por PHP.


    11. Crear una página de información de PHP

    PHP tiene una función muy útil para comprobar la configuración instalada:

    <?php
    phpinfo();
    ?>

    Podemos crear un archivo llamado:

    info.php

    dentro de nuestra carpeta mi_proyecto.

    La estructura quedaría así:

    htdocs/
    └── mi_proyecto/
        ├── index.php
        └── info.php

    Dentro de info.php escribimos:

    <?php
    phpinfo();
    ?>

    Después abrimos en el navegador:

    http://localhost/mi_proyecto/info.php

    Aparecerá una página con información sobre la versión de PHP, configuración, extensiones activas y otros datos del entorno.

    Esta página es útil para comprobar que PHP funciona correctamente.

    Importante: en proyectos reales no se debe dejar publicado un archivo phpinfo(), porque muestra demasiada información del servidor.


    12. Acceder a phpMyAdmin

    Si hemos iniciado Apache y MySQL/MariaDB desde el panel de control de XAMPP, podemos acceder a phpMyAdmin desde el navegador:

    http://localhost/phpmyadmin

    phpMyAdmin nos permite gestionar bases de datos desde una interfaz web.

    Desde ahí podremos:

    • crear bases de datos;
    • crear tablas;
    • insertar datos;
    • modificar registros;
    • ejecutar consultas SQL;
    • importar y exportar bases de datos.

    Más adelante usaremos esta herramienta para conectar nuestras aplicaciones PHP con una base de datos.


    13. Problemas frecuentes

    Apache no arranca

    Uno de los problemas más habituales es que Apache no pueda iniciarse porque el puerto 80 ya está ocupado.

    El puerto 80 puede estar siendo usado por otros programas como:

    • IIS de Windows;
    • Skype;
    • Docker;
    • otro servidor web;
    • alguna herramienta de desarrollo.

    Soluciones posibles:

    1. Cerrar el programa que está usando el puerto 80.
    2. Cambiar el puerto de Apache.
    3. Ejecutar XAMPP como administrador en Windows.

    Si cambiamos Apache al puerto 8080, accederíamos así:

    http://localhost:8080

    Y nuestros proyectos se abrirían así:

    http://localhost:8080/mi_proyecto/index.php

    MySQL o MariaDB no arranca

    Puede ocurrir que la base de datos no arranque porque el puerto 3306 esté ocupado.

    Ese puerto puede estar siendo usado por otra instalación de MySQL o MariaDB.

    Soluciones posibles:

    1. Detener el otro servicio de MySQL/MariaDB.
    2. Cambiar el puerto de la base de datos en XAMPP.
    3. Reiniciar el equipo y probar de nuevo.
    4. Revisar los logs desde el panel de control.

    El navegador muestra el código PHP en lugar del resultado

    Si al abrir un archivo PHP vemos el código escrito en pantalla, normalmente significa que estamos abriendo el archivo directamente desde el sistema de archivos.

    Ejemplo incorrecto:

    file:///C:/xampp/htdocs/mi_proyecto/index.php

    Forma correcta:

    http://localhost/mi_proyecto/index.php

    Los archivos PHP deben ejecutarse a través del servidor, no abrirse directamente como archivos locales.


    Error 404 al abrir el proyecto

    Un error 404 significa que el servidor no encuentra el archivo o carpeta que estamos solicitando.

    Debemos comprobar:

    • que Apache está iniciado;
    • que la carpeta del proyecto está dentro de htdocs;
    • que el nombre de la carpeta está bien escrito;
    • que el archivo index.php existe;
    • que la URL coincide con la estructura real.

    Por ejemplo, si tenemos:

    C:\xampp\htdocs\mi_proyecto\index.php

    la URL correcta será:

    http://localhost/mi_proyecto/index.php

    14. Buenas prácticas para organizar proyectos

    Dentro de htdocs podemos crear una carpeta para cada proyecto.

    Ejemplo:

    htdocs/
    ├── proyecto_01/
    │   └── index.php
    ├── proyecto_02/
    │   └── index.php
    └── pruebas_php/
        └── index.php

    Es recomendable usar nombres de carpetas sencillos:

    • sin espacios;
    • sin acentos;
    • en minúsculas;
    • usando guiones bajos o guiones medios si hace falta.

    Ejemplos recomendados:

    mi_proyecto
    tienda_online
    practica_01
    reservas_camping

    Ejemplos poco recomendables:

    Mi Proyecto
    Práctica PHP número 1
    web final!!!

    15. Resumen del proceso

    El proceso básico para trabajar con XAMPP será siempre parecido:

    1. Abrir XAMPP.
    2. Iniciar Apache.
    3. Iniciar MySQL/MariaDB si vamos a usar base de datos.
    4. Crear una carpeta de proyecto dentro de htdocs.
    5. Crear archivos .php.
    6. Abrir el proyecto desde el navegador usando localhost.
    7. Comprobar el resultado.
    8. Corregir el código y volver a probar.

    La idea principal es entender que PHP no se ejecuta en el navegador. PHP se ejecuta en el servidor local que nos proporciona XAMPP. El navegador solo recibe el resultado final, normalmente HTML.


    16. Actividad propuesta para el alumno

    Objetivo

    Comprobar que XAMPP está correctamente instalado y que PHP funciona en el equipo.

    Pasos

    1. Instala XAMPP en tu sistema operativo.
    2. Abre el panel de control de XAMPP.
    3. Inicia Apache.
    4. Abre en el navegador:
    http://localhost
    1. Crea una carpeta dentro de htdocs llamada:
    prueba_php
    1. Dentro de esa carpeta crea un archivo llamado:
    index.php
    1. Escribe el siguiente código:
    <!DOCTYPE html>
    <html lang="es">
    <head>
        <meta charset="UTF-8">
        <title>Prueba PHP</title>
    </head>
    <body>
    
        <h1>Prueba de XAMPP y PHP</h1>
    
        <p>
            <?php
                echo "PHP está funcionando correctamente.";
            ?>
        </p>
    
    </body>
    </html>
    1. Abre en el navegador:
    http://localhost/prueba_php/index.php
    1. Comprueba que se muestra correctamente el mensaje.

    Preguntas de reflexión

    1. ¿Por qué no podemos abrir un archivo PHP directamente con doble clic?
    2. ¿Qué papel cumple Apache dentro de XAMPP?
    3. ¿Qué diferencia hay entre abrir localhost y abrir un archivo con file:///?
    4. ¿Dónde debemos guardar nuestros proyectos PHP?
    5. ¿Para qué sirve phpMyAdmin?
    6. ¿Qué ocurre si Apache no está iniciado?

    17. Conclusión

    XAMPP nos permite disponer de un entorno de desarrollo local para aprender y practicar PHP sin necesidad de contratar un servidor externo.

    Gracias a XAMPP podemos simular en nuestro propio ordenador el funcionamiento básico de una aplicación web real: el navegador hace una petición, Apache la recibe, PHP interpreta el código y el navegador muestra el resultado final.

    Este entorno será la base inicial del curso. Más adelante podremos comparar esta forma de trabajo con otras opciones más avanzadas, como servidores remotos, máquinas virtuales o contenedores Docker.

  • 1.5 – Visual Studio Code para programar en PHP 📹

    1.5 – Visual Studio Code para programar en PHP 📹

    Cuando empezamos a programar en PHP, una de las primeras decisiones que tenemos que tomar es qué herramienta vamos a utilizar para escribir nuestro código. Existen IDEs muy completos, como PhpStorm, NetBeans o Eclipse PDT, pero para un curso desde cero una de las opciones más equilibradas es Visual Studio Code.

    Visual Studio Code, normalmente conocido como VS Code, es un editor de código gratuito, ligero, multiplataforma y muy flexible. No es un IDE exclusivo para PHP, pero gracias a sus extensiones puede convertirse en un entorno muy potente para desarrollar aplicaciones web.

    En este artículo veremos por qué VS Code es una buena opción para trabajar con PHP, qué ventajas tiene para el aprendizaje y qué extensiones conviene instalar.


    📹 Instalación VSCODE

    ¿Qué es Visual Studio Code?

    Visual Studio Code es un editor de código desarrollado por Microsoft. Está disponible para Windows, macOS y Linux, por lo que resulta muy cómodo en un entorno educativo donde cada alumno puede tener un sistema operativo diferente.

    A diferencia de otros IDEs más pesados, VS Code parte de una base sencilla y se puede ampliar mediante extensiones. Esto significa que podemos instalar solo lo que necesitamos para cada momento del curso.

    Por ejemplo, en un proyecto PHP podemos trabajar con archivos como estos:

    mi-proyecto-php/
    ├── index.php
    ├── contacto.php
    ├── productos.php
    ├── css/
    │ └── estilos.css
    ├── js/
    │ └── app.js
    ├── includes/
    │ ├── cabecera.php
    │ └── pie.php
    └── README.md

    Desde VS Code podemos abrir toda la carpeta del proyecto y trabajar cómodamente con todos estos archivos.


    📹 Mí primer Hola Mundo

    ¿Por qué usar VS Code para PHP?

    PHP es un lenguaje que se ejecuta normalmente en un servidor web. Es decir, nosotros escribimos el código en archivos .php, pero para ver el resultado necesitamos ejecutarlo mediante un servidor como Apache, Nginx, el servidor integrado de PHP o un entorno como XAMPP, MAMP, Laragon o Docker.

    VS Code encaja muy bien en este flujo porque nos permite escribir, organizar y revisar el código de forma clara.

    El flujo básico sería:

    Escribir código en VS Code

    Guardar el archivo PHP

    Ejecutarlo mediante un servidor

    Ver el resultado en el navegador

    Corregir errores y volver a probar

    Esta forma de trabajar ayuda mucho al alumno, porque ve claramente qué papel cumple cada herramienta.

    HerramientaFunción
    VS CodeEscribir y organizar el código
    PHPInterpretar el código del servidor
    Apache / Nginx / servidor PHPServir la aplicación web
    NavegadorMostrar el resultado
    MySQL / MariaDBAlmacenar los datos
    phpMyAdmin / DBeaver / DataGripGestionar la base de datos

    Ventajas de VS Code en un curso de PHP

    Es gratuito

    Una ventaja muy importante es que VS Code es gratuito. Esto permite que todos los alumnos puedan instalarlo sin depender de licencias.

    Para un entorno educativo esto es fundamental, porque evita problemas económicos y facilita que todos trabajen con la misma herramienta.


    Funciona en Windows, macOS y Linux

    VS Code está disponible para los principales sistemas operativos. Esto nos permite usarlo en diferentes escenarios:

    SistemaEntorno PHP habitual
    WindowsXAMPP, Laragon, Docker
    macOSMAMP, XAMPP, Docker, PHP instalado con Homebrew
    LinuxApache, Nginx, PHP, Docker

    El editor será el mismo, aunque el servidor PHP pueda cambiar según el sistema operativo.


    Es ligero y sencillo

    VS Code no es tan pesado como un IDE completo. Esto hace que sea más rápido de instalar, abrir y utilizar.

    Para alumnos que empiezan, esto es una ventaja importante. Una interfaz demasiado cargada puede distraer más que ayudar.

    Con VS Code podemos empezar con algo muy simple:

    <?php
    echo "Hola mundo desde PHP";
    ?>

    Y poco a poco ir avanzando hacia proyectos más completos.


    Se adapta al nivel del alumno

    Otra ventaja es que podemos ir añadiendo extensiones según avanza el curso.

    Al principio podemos instalar solo lo básico. Más adelante, cuando trabajemos con bases de datos, Git, depuración o Docker, podremos añadir nuevas extensiones.

    Esto permite que el alumno no se vea saturado desde el primer día.


    VS Code no ejecuta PHP por sí solo

    Este punto es muy importante.

    VS Code sirve para escribir código, pero no sustituye al servidor PHP.

    Para ejecutar un archivo PHP necesitamos tener PHP instalado y, normalmente, trabajar con un servidor web.

    Por ejemplo, si tenemos este archivo:

    <?php
    $nombre = "Ana";
    echo "Hola, " . $nombre;
    ?>

    No basta con abrirlo directamente en el navegador como si fuera un archivo HTML. Necesitamos ejecutarlo desde un servidor.

    Una opción rápida es usar el servidor integrado de PHP. Desde la carpeta del proyecto podemos escribir:

    php -S localhost:8000

    Después abrimos el navegador y accedemos a:

    http://localhost:8000

    Para proyectos más completos podemos usar Apache, Nginx, XAMPP, MAMP, Laragon o Docker.


    Extensiones recomendadas para PHP en VS Code

    Una de las grandes ventajas de VS Code es su sistema de extensiones. A continuación veremos algunas de las más útiles para trabajar con PHP.

    📹 Instalación de Extensiones o Plugins


    PHP Intelephense

    PHP Intelephense es una de las extensiones más importantes para programar en PHP con VS Code.

    Añade funciones como:

    FunciónUtilidad
    AutocompletadoAyuda a escribir funciones, variables, clases y métodos
    Detección de erroresMarca posibles errores antes de ejecutar
    Ir a definiciónPermite saltar a donde está definida una función o clase
    Ayuda contextualMuestra información sobre parámetros y métodos
    Mejor soporte para proyectos grandesEntiende mejor la estructura del código

    Esta extensión debería instalarse desde el principio del curso.

    Ejemplo:

    <?php

    function saludar($nombre) {
    return "Hola, " . $nombre;
    }

    echo saludar("Laura");

    ?>

    Con PHP Intelephense, VS Code nos ayudará a detectar funciones, parámetros y posibles errores de escritura.


    PHP Debug

    PHP Debug permite conectar VS Code con Xdebug, una herramienta de depuración para PHP.

    Depurar significa ejecutar el programa paso a paso para ver qué está ocurriendo realmente. Esto es muy útil cuando un programa no falla por sintaxis, pero no hace lo que esperamos.

    Por ejemplo:

    <?php

    $edad = 17;

    if ($edad >= 18) {
    echo "Puede acceder";
    } else {
    echo "No puede acceder";
    }

    ?>

    Con depuración podemos detener el programa antes del if y comprobar el valor real de la variable $edad.

    PHP Debug permite:

    FunciónUtilidad
    Puntos de interrupciónParar el programa en una línea concreta
    Ejecución paso a pasoVer cómo avanza el programa
    Inspección de variablesComprobar valores durante la ejecución
    Depuración de formulariosVer datos enviados por GET o POST
    Detección de errores lógicosEncontrar fallos que no son de sintaxis

    No es necesario instalarla el primer día, pero sí es muy recomendable cuando los alumnos ya trabajen con formularios, funciones, sesiones y bases de datos.


    PHP DocBlocker

    PHP DocBlocker ayuda a crear comentarios de documentación para funciones, clases y métodos.

    Por ejemplo, si tenemos esta función:

    function calcularTotal($precio, $cantidad) {
    return $precio * $cantidad;
    }

    Podemos documentarla así:

    /**
    * Calcula el precio total de una compra.
    *
    * @param float $precio
    * @param int $cantidad
    * @return float
    */
    function calcularTotal($precio, $cantidad) {
    return $precio * $cantidad;
    }

    Esta extensión resulta útil cuando empezamos a trabajar con funciones y programación orientada a objetos.

    Documentar el código es una buena práctica que ayuda a que otros programadores puedan entender mejor nuestro proyecto.


    Prettier

    Prettier es una extensión para formatear código.

    En proyectos PHP no solo escribimos PHP. También solemos trabajar con HTML, CSS y JavaScript. Prettier ayuda a mantener estos archivos ordenados y con un formato consistente.

    Por ejemplo, puede ayudarnos con código HTML como este:

    <!DOCTYPE html>
    <html lang="es">
    <head>
    <meta charset="UTF-8">
    <title>Mi página PHP</title>
    </head>
    <body>
    <h1>Bienvenido</h1>
    </body>
    </html>

    Su principal utilidad es que todos los alumnos mantengan una estructura más limpia y parecida.


    GitLens

    GitLens mejora la integración de Git dentro de VS Code.

    Cuando los alumnos empiecen a trabajar con repositorios, entregas en GitHub o control de versiones, esta extensión resulta muy útil.

    Permite ver:

    FunciónUtilidad
    Historial de cambiosConsultar modificaciones realizadas
    Autor de una líneaSaber quién cambió una parte del código
    Comparación de versionesRevisar diferencias entre archivos
    Información del repositorioVer ramas, commits y cambios pendientes

    No es imprescindible para empezar con PHP, pero sí muy recomendable cuando el curso avance hacia proyectos reales.


    Material Icon Theme

    Material Icon Theme cambia los iconos de archivos y carpetas dentro de VS Code.

    Aunque pueda parecer una extensión estética, en clase resulta bastante útil porque ayuda al alumno a identificar rápidamente los tipos de archivos.

    Por ejemplo:

    ArchivoTipo
    index.phpArchivo PHP
    estilos.cssArchivo CSS
    app.jsArchivo JavaScript
    conexion.sqlArchivo SQL
    README.mdArchivo Markdown

    Visualmente ayuda a que los proyectos sean más fáciles de entender.


    Auto Rename Tag

    Auto Rename Tag es una extensión muy útil cuando trabajamos con HTML.

    Cuando cambiamos una etiqueta de apertura, la extensión modifica automáticamente la etiqueta de cierre.

    Por ejemplo, si cambiamos:

    <h1>Título</h1>

    por:

    <h2>Título</h2>

    La extensión nos ayuda a evitar que una etiqueta quede mal cerrada.

    Esto es especialmente útil en proyectos PHP donde mezclamos HTML con código PHP.


    Error Lens

    Error Lens muestra los errores y avisos directamente en la línea de código.

    Esto puede ayudar mucho a los alumnos, porque no tienen que buscar el error en un panel inferior. Lo ven directamente en el lugar donde ocurre.

    Resulta útil cuando ya tenemos instaladas extensiones de análisis como PHP Intelephense.


    SQLTools

    SQLTools permite trabajar con bases de datos desde VS Code.

    Con esta extensión, y su driver correspondiente para MySQL o MariaDB, podemos conectarnos a una base de datos, lanzar consultas y revisar resultados.

    Aun así, para alumnos que empiezan puede ser más didáctico usar primero phpMyAdmin, porque muestra visualmente las tablas, campos y relaciones.

    Una progresión recomendable sería:

    NivelHerramienta
    InicialphpMyAdmin
    MedioDBeaver
    AvanzadoSQLTools en VS Code o DataGrip

    Extensiones recomendadas según el momento del curso

    No conviene instalar todas las extensiones desde el primer día. Es mejor ir incorporándolas según avance el curso.

    Primeros días del curso

    ExtensiónMotivo
    PHP IntelephenseAyuda principal para programar en PHP
    Material Icon ThemeMejora la visualización de archivos
    PrettierFormatea HTML, CSS y JavaScript

    Cuando trabajemos con HTML, CSS y formularios

    ExtensiónMotivo
    Auto Rename TagAyuda con etiquetas HTML
    Live ServerVista previa de HTML, CSS y JS
    HTML CSS SupportAyuda con clases CSS

    Cuando trabajemos con bases de datos

    ExtensiónMotivo
    SQLToolsConsultas SQL desde VS Code
    SQLTools MySQL/MariaDB DriverConexión con MySQL o MariaDB
    PHP IntelephenseAyuda con código PHP de conexión

    Cuando trabajemos con Git y GitHub

    ExtensiónMotivo
    GitLensHistorial y revisión de cambios
    GitHub Pull RequestsTrabajo con repositorios de GitHub

    Cuando trabajemos con depuración

    ExtensiónMotivo
    PHP DebugDepuración con Xdebug
    Error LensVisualización clara de errores

    Cuando trabajemos con Docker

    ExtensiónMotivo
    DockerGestión de contenedores
    Dev ContainersDesarrollo dentro de contenedores

    Configuración básica recomendada

    Podemos configurar VS Code para que sea más cómodo trabajar con PHP.

    Para ello, abrimos la configuración en formato JSON y podemos añadir algo similar a esto:

    {
    "editor.formatOnSave": true,
    "editor.wordWrap": "on",
    "files.autoSave": "afterDelay",
    "php.suggest.basic": false
    }

    Veamos qué hace cada opción:

    OpciónFunción
    editor.formatOnSaveFormatea el código al guardar
    editor.wordWrapAjusta líneas largas a la pantalla
    files.autoSaveGuarda automáticamente después de un breve tiempo
    php.suggest.basicDesactiva sugerencias básicas de PHP para evitar duplicados con Intelephense

    Esta configuración puede variar según el nivel del alumno y las extensiones instaladas.


    Estructura sencilla para un proyecto PHP

    Para empezar, podemos usar una estructura muy simple:

    curso-php/
    ├── index.php
    ├── contacto.php
    ├── productos.php
    ├── includes/
    │ ├── cabecera.php
    │ ├── menu.php
    │ └── pie.php
    ├── css/
    │ └── estilos.css
    ├── js/
    │ └── app.js
    └── img/
    └── logo.png

    Esta estructura permite explicar conceptos básicos como:

    Carpeta o archivoUso
    index.phpPágina principal
    includes/Fragmentos reutilizables
    css/Hojas de estilo
    js/Archivos JavaScript
    img/Imágenes del proyecto

    Más adelante, cuando el proyecto crezca, podremos usar una estructura más organizada:

    proyecto-php/
    ├── public/
    │ ├── index.php
    │ ├── css/
    │ ├── js/
    │ └── img/
    ├── config/
    │ └── conexion.php
    ├── modelos/
    │ └── Producto.php
    ├── controladores/
    │ └── ProductoController.php
    ├── vistas/
    │ └── productos/
    │ ├── listar.php
    │ ├── crear.php
    │ └── editar.php
    └── README.md

    Esta segunda estructura ya nos acerca a proyectos más profesionales.


    Ejemplo básico en VS Code

    Podemos crear un archivo llamado index.php con este contenido:

    <?php

    $titulo = "Mi primera página con PHP";
    $mensaje = "Estoy aprendiendo a programar aplicaciones web.";

    ?>

    <!DOCTYPE html>
    <html lang="es">
    <head>
    <meta charset="UTF-8">
    <title><?php echo $titulo; ?></title>
    </head>
    <body>

    <h1><?php echo $titulo; ?></h1>
    <p><?php echo $mensaje; ?></p>

    </body>
    </html>

    Este ejemplo es interesante porque muestra una de las características habituales de PHP: la mezcla de código PHP con HTML.

    Desde VS Code escribimos el código, pero para verlo correctamente tendremos que ejecutarlo desde un servidor PHP.


    Recomendación para clase

    Para un curso de PHP desde cero, mi recomendación sería empezar con pocas extensiones:

    ExtensiónPrioridad
    PHP IntelephenseObligatoria
    Material Icon ThemeRecomendada
    PrettierRecomendada
    Auto Rename TagRecomendada cuando usemos HTML
    GitLensCuando empecemos con Git
    PHP DebugCuando empecemos con depuración
    SQLToolsCuando avancemos con bases de datos
    DockerCuando trabajemos con contenedores

    No es buena idea instalar demasiadas extensiones al principio. Puede parecer que estamos mejorando el entorno, pero en realidad podemos confundir al alumno.

    Lo ideal es que el entorno crezca al mismo ritmo que el curso.


    Conclusión

    Visual Studio Code es una herramienta muy adecuada para aprender PHP porque combina sencillez, potencia y flexibilidad.

    Nos permite empezar con scripts básicos y avanzar poco a poco hacia proyectos más completos con HTML, CSS, JavaScript, formularios, sesiones, bases de datos, Git, depuración y Docker.

    Pero conviene recordar una idea importante:

    VS Code no es el servidor. VS Code es la herramienta donde escribimos el código. PHP necesita un entorno de ejecución para funcionar.

    Por eso, en un curso de PHP deberíamos enseñar siempre la relación entre el editor, el servidor, el lenguaje y el navegador.

    El objetivo no es solamente aprender a usar VS Code. El objetivo es entender el proceso completo de desarrollo de una aplicación web con PHP:

    Editor → Código PHP → Servidor → Navegador → Pruebas → Corrección → Nueva versión
  • 1.6 – Sintaxis, variables, tipos de datos y salida por pantalla

    1.6 – Sintaxis, variables, tipos de datos y salida por pantalla

    Introducción

    Cuando empezamos a programar en PHP, lo primero que debemos entender no es todavía cómo crear una aplicación completa, ni cómo conectar con una base de datos, ni cómo hacer un formulario avanzado. Antes de todo eso necesitamos aprender a escribir PHP correctamente.

    PHP es un lenguaje que normalmente se ejecuta en el servidor. Eso significa que el navegador no interpreta directamente el código PHP. El navegador pide una página al servidor, el servidor ejecuta el PHP y finalmente devuelve al navegador una respuesta, normalmente HTML. Por eso, aunque nosotros escribamos código PHP, el usuario final normalmente solo recibe el resultado.

    En este primer tema vamos a trabajar la base de la sintaxis de PHP: cómo se abre y se cierra un bloque PHP, cómo se escriben instrucciones, cómo se declaran variables, qué tipos de datos básicos existen y cómo podemos mostrar información en pantalla usando herramientas como echo, print, var_dump(), print_r(), printf() o var_export().

    La idea no es memorizarlo todo de golpe, sino empezar a leer y escribir código PHP con seguridad.


    1. Cómo se escribe código PHP

    Un archivo PHP normalmente tiene extensión .php. Dentro de ese archivo podemos escribir HTML normal y, cuando queramos que el servidor ejecute código PHP, debemos abrir un bloque PHP.

    La forma estándar de abrir PHP es:

    <?php
    // Código PHP aquí
    ?>

    La etiqueta de apertura <?php indica al intérprete que a partir de ese punto empieza código PHP. La etiqueta de cierre ?> indica que termina el bloque PHP. La documentación oficial de PHP explica que estas etiquetas sirven para marcar los límites del código PHP que debe ejecutarse dentro del archivo.

    Por ejemplo:

    <!DOCTYPE html>
    <html lang="es">
    <head>
    <meta charset="UTF-8">
    <title>Mi primera página PHP</title>
    </head>
    <body>

    <h1>Bienvenido a mi página</h1>

    <?php
    echo "Este texto lo ha generado PHP";
    ?>

    </body>
    </html>

    En este ejemplo hay una mezcla de HTML y PHP. El HTML se entrega tal cual al navegador, mientras que la parte PHP se ejecuta en el servidor. El resultado final que verá el navegador será algo parecido a esto:

    <h1>Bienvenido a mi página</h1>
    Este texto lo ha generado PHP

    El navegador no ve el código PHP original. Solo ve el resultado.


    2. La etiqueta <?php

    La etiqueta correcta y recomendable para abrir PHP es:

    <?php

    Es importante no confundirla con otras formas antiguas o menos recomendables como:

    <?

    Esa forma corta puede funcionar en algunos servidores, pero depende de la configuración de PHP. Por eso, para aprender bien y evitar problemas, usaremos siempre <?php.

    También existe una etiqueta corta especial para imprimir valores:

    <?= $variable ?>

    Esta etiqueta equivale a escribir:

    <?php echo $variable; ?>

    Es decir, estas dos líneas hacen lo mismo:

    <p><?= $nombre ?></p>

    <p><?php echo $nombre; ?></p>

    La etiqueta <?= es una forma abreviada de <?php echo, y PHP la reconoce como una etiqueta de salida corta.

    Para un alumno que está empezando, mi recomendación es clara: al principio utiliza siempre <?php echo ... ?>. Cuando ya estés cómodo leyendo código PHP, puedes empezar a usar <?= ... ?> en plantillas HTML porque es más cómodo y limpio.


    3. ¿Hay que cerrar siempre PHP con ?>?

    En archivos donde mezclamos HTML y PHP, sí es normal cerrar el bloque PHP:

    <h1>
    <?php echo "Hola mundo"; ?>
    </h1>

    Pero cuando un archivo contiene solamente PHP, es habitual no cerrar la etiqueta final.

    Por ejemplo:

    <?php

    $nombre = "Laura";
    $edad = 25;

    echo $nombre;

    En este caso no hemos puesto ?> al final. Esto es habitual en archivos PHP puros, especialmente en proyectos profesionales. La razón es sencilla: evita errores provocados por espacios o saltos de línea accidentales después del cierre de PHP.

    Para esta primera parte del curso podemos usar ambas formas, pero conviene que el alumno vaya entendiendo esta regla práctica:

    Cuando el archivo mezcla HTML y PHP, podemos cerrar PHP.
    Cuando el archivo solo contiene PHP, normalmente dejamos el archivo sin cierre final.


    4. Las instrucciones en PHP

    Una instrucción es una orden que le damos al lenguaje. Por ejemplo:

    echo "Hola mundo";

    Esta instrucción le dice a PHP que muestre el texto "Hola mundo".

    En PHP, la mayoría de instrucciones terminan con punto y coma:

    $nombre = "Ana";
    $edad = 20;
    echo $nombre;

    El punto y coma ; es muy importante. Si se nos olvida, PHP normalmente mostrará un error de sintaxis.

    Ejemplo incorrecto:

    <?php
    $nombre = "Ana"
    echo $nombre;

    El problema está en que falta el punto y coma después de "Ana".

    La versión correcta sería:

    <?php
    $nombre = "Ana";
    echo $nombre;

    Al principio puede parecer un detalle pequeño, pero muchos errores de principiantes en PHP vienen precisamente de olvidar un ;, una comilla o una llave.


    5. Comentarios en PHP

    Los comentarios son textos que escribimos dentro del código, pero que PHP no ejecuta. Sirven para explicar algo, dejar notas o desactivar temporalmente una línea.

    PHP permite comentarios de una línea:

    <?php

    // Esto es un comentario de una línea

    $nombre = "Carlos"; // También puedo comentar al final de una línea

    echo $nombre;

    También permite comentarios de varias líneas:

    <?php

    /*
    Este es un comentario
    de varias líneas.
    PHP no ejecutará nada de lo que haya aquí dentro.
    */

    echo "Hola";

    Los comentarios deben usarse con cabeza. Un buen comentario no explica lo evidente, sino la intención del código.

    Este comentario aporta poco:

    <?php

    // Creamos una variable nombre
    $nombre = "Ana";

    Este comentario sí puede ser útil:

    <?php

    // Guardamos el nombre que se mostrará en la cabecera de la página
    $nombre = "Ana";

    6. Variables en PHP

    Una variable es un espacio donde guardamos un valor. Ese valor puede ser un texto, un número, un verdadero/falso, una lista de datos, etc.

    En PHP, todas las variables empiezan con el símbolo $.

    <?php

    $nombre = "Ana";
    $edad = 22;
    $precio = 19.99;
    $activo = true;

    Aquí hemos creado cuatro variables:

    $nombre guarda un texto.
    $edad guarda un número entero.
    $precio guarda un número decimal.
    $activo guarda un valor booleano, es decir, verdadero o falso.

    La documentación oficial de PHP recoge las variables como una parte fundamental de la referencia del lenguaje.

    En PHP no hace falta declarar el tipo de dato al crear una variable. No escribimos esto:

    string $nombre = "Ana";
    int $edad = 22;

    Aunque PHP sí permite usar declaraciones de tipo en funciones y clases, en la creación básica de variables normalmente escribimos directamente:

    $nombre = "Ana";
    $edad = 22;

    PHP detecta el tipo de dato según el valor que le asignamos.


    7. Reglas básicas para nombres de variables

    Una variable en PHP debe empezar siempre con $.

    Después del $, el nombre de la variable debe empezar por una letra o por guion bajo _. No debe empezar por un número.

    Correcto:

    <?php

    $nombre = "Laura";
    $_contador = 1;
    $precioFinal = 29.99;
    $nombre_usuario = "admin";

    Incorrecto:

    <?php

    $1nombre = "Laura";
    $precio-final = 29.99;
    $nombre usuario = "admin";

    También debemos recordar que PHP distingue entre mayúsculas y minúsculas en los nombres de variables.

    <?php

    $nombre = "Ana";
    $Nombre = "Carlos";

    echo $nombre;
    echo $Nombre;

    Aunque se parecen, $nombre y $Nombre son dos variables diferentes.

    Esto es importante porque puede provocar errores difíciles de ver:

    <?php

    $usuario = "antonio";

    echo $Usuario;

    Aquí hemos creado $usuario, pero luego intentamos mostrar $Usuario. Para PHP son variables distintas. La segunda no tiene valor asignado.

    Mi recomendación para alumnos es usar siempre nombres claros y consistentes:

    $nombreUsuario = "antonio";
    $precioProducto = 15.50;
    $estaConectado = true;

    Evitar nombres como estos:

    $x = "antonio";
    $p = 15.50;
    $ec = true;

    Funcionan, pero son mucho menos claros.


    8. Asignar valores a variables

    Para guardar un valor en una variable usamos el operador de asignación =.

    <?php

    $nombre = "Lucía";

    Esta línea no significa “nombre es igual a Lucía” en sentido matemático. Significa: guarda el valor "Lucía" dentro de la variable $nombre.

    Podemos cambiar el valor de una variable más adelante:

    <?php

    $nombre = "Lucía";
    echo $nombre;

    $nombre = "Mario";
    echo $nombre;

    Primero $nombre vale "Lucía". Después cambia y pasa a valer "Mario".

    También podemos crear una variable a partir de otras variables:

    <?php

    $precio = 100;
    $iva = 21;

    $precioConIva = $precio + ($precio * $iva / 100);

    echo $precioConIva;

    En este caso, PHP calcula el precio con IVA y guarda el resultado en $precioConIva.


    9. Tipos de datos básicos en PHP

    Aunque PHP permite trabajar de forma flexible, es fundamental entender los tipos de datos. Un tipo de dato indica qué clase de valor tenemos entre manos.

    No es lo mismo esto:

    $edad = 25;

    que esto:

    $edad = "25";

    En el primer caso tenemos un número entero. En el segundo caso tenemos un texto que contiene los caracteres 2 y 5.

    PHP tiene varios tipos de datos. En este tema vamos a trabajar los más importantes para empezar: cadenas de texto, enteros, decimales, booleanos, nulos y arrays. PHP incluye en su referencia oficial una sección completa dedicada a los tipos del lenguaje, como booleanos, enteros, números de punto flotante, strings, arrays, objetos, null y otros.


    10. Texto o string

    Un string es una cadena de texto. Puede contener letras, números, espacios y símbolos.

    <?php

    $nombre = "Ana";
    $ciudad = "Madrid";
    $mensaje = "Bienvenido al curso de PHP";

    Podemos escribir strings usando comillas dobles:

    $nombre = "Ana";

    O comillas simples:

    $nombre = 'Ana';

    Las dos formas sirven, pero tienen una diferencia importante. Con comillas dobles, PHP puede interpretar variables dentro del texto:

    <?php

    $nombre = "Ana";

    echo "Hola $nombre";

    Resultado:

    Hola Ana

    Con comillas simples, PHP no sustituye la variable:

    <?php

    $nombre = "Ana";

    echo 'Hola $nombre';

    Resultado:

    Hola $nombre

    Por eso, si queremos insertar variables directamente dentro de un texto, podemos usar comillas dobles.

    También podemos concatenar textos usando el punto .:

    <?php

    $nombre = "Ana";

    echo "Hola " . $nombre;

    Resultado:

    Hola Ana

    La concatenación es muy importante en PHP. El operador . une textos.

    Otro ejemplo:

    <?php

    $nombre = "Carlos";
    $edad = 30;

    echo "Me llamo " . $nombre . " y tengo " . $edad . " años.";

    Resultado:

    Me llamo Carlos y tengo 30 años.

    11. Números enteros o integer

    Un número entero es un número sin decimales.

    <?php

    $edad = 25;
    $stock = 100;
    $temperatura = -3;

    Podemos hacer operaciones con ellos:

    <?php

    $unidades = 5;
    $precioUnidad = 10;

    $total = $unidades * $precioUnidad;

    echo $total;

    Resultado:

    50

    Los enteros se usan constantemente en programación: edades, cantidades, identificadores, contadores, posiciones, intentos, puntuaciones, etc.


    12. Números decimales o float

    Un número decimal en PHP se suele representar como float.

    <?php

    $precio = 19.99;
    $altura = 1.75;
    $notaMedia = 8.5;

    Es importante recordar que en programación se usa el punto . como separador decimal, no la coma.

    Correcto:

    $precio = 19.99;

    Incorrecto:

    $precio = 19,99;

    Con decimales también podemos operar:

    <?php

    $precio = 19.99;
    $descuento = 5;

    $precioFinal = $precio - $descuento;

    echo $precioFinal;

    Resultado:

    14.99

    13. Booleanos o boolean

    Un booleano solo puede tener dos valores:

    true
    false

    Se utilizan para representar estados de verdadero o falso.

    <?php

    $usuarioActivo = true;
    $tienePermiso = false;
    $productoDisponible = true;

    Los booleanos serán fundamentales cuando trabajemos con condiciones.

    Por ejemplo:

    <?php

    $usuarioActivo = true;

    if ($usuarioActivo) {
    echo "El usuario puede acceder.";
    } else {
    echo "El usuario no puede acceder.";
    }

    Aunque todavía no hayamos estudiado en profundidad los if, este ejemplo nos permite ver para qué sirve un booleano. La variable $usuarioActivo representa una decisión: sí o no, verdadero o falso.


    14. Valor nulo o null

    null representa la ausencia de valor.

    <?php

    $telefono = null;

    No significa que el teléfono sea un texto vacío. No significa que sea cero. Significa que no hay valor.

    Esto es diferente:

    $telefono = "";

    Aquí sí hay un valor: una cadena vacía.

    Y esto también es diferente:

    $telefono = 0;

    Aquí hay un valor numérico: cero.

    null se utiliza mucho cuando un dato todavía no existe, cuando no se ha rellenado o cuando queremos indicar expresamente que una variable no tiene contenido.

    Ejemplo:

    <?php

    $segundoApellido = null;

    var_dump($segundoApellido);

    Resultado aproximado:

    NULL

    15. Arrays

    Un array permite guardar varios valores dentro de una misma variable. Según la documentación oficial, en PHP un array es realmente un mapa ordenado, es decir, una estructura que asocia claves con valores. Esto permite usarlo como lista, diccionario, colección y otras estructuras.

    Un array sencillo sería:

    <?php

    $frutas = ["manzana", "pera", "plátano"];

    Podemos acceder a cada elemento usando su posición. En PHP, como en muchos lenguajes, las posiciones empiezan en cero.

    <?php

    $frutas = ["manzana", "pera", "plátano"];

    echo $frutas[0];
    echo $frutas[1];
    echo $frutas[2];

    Resultado:

    manzana
    pera
    plátano

    También podemos crear arrays asociativos, donde nosotros indicamos una clave:

    <?php

    $usuario = [
    "nombre" => "Ana",
    "email" => "ana@example.com",
    "edad" => 28
    ];

    echo $usuario["nombre"];
    echo $usuario["email"];
    echo $usuario["edad"];

    Resultado:

    Ana
    ana@example.com
    28

    Los arrays son muy importantes en PHP. Los usaremos más adelante para manejar datos de formularios, resultados de bases de datos, configuraciones, sesiones y muchas otras partes de una aplicación web.


    16. Cambios de tipo en PHP

    PHP es un lenguaje flexible. Una misma variable puede contener primero un texto y después un número.

    <?php

    $dato = "Hola";
    $dato = 25;
    $dato = true;

    Esto funciona, pero no siempre es buena idea abusar de ello.

    Cuando estamos aprendiendo, conviene que una variable tenga un sentido claro. Si una variable se llama $edad, debería guardar una edad. Si se llama $nombre, debería guardar un nombre. Si se llama $precio, debería guardar un precio.

    Código poco claro:

    <?php

    $dato = "Ana";
    $dato = 25;
    $dato = true;

    Código más claro:

    <?php

    $nombre = "Ana";
    $edad = 25;
    $usuarioActivo = true;

    La flexibilidad de PHP es cómoda, pero también puede esconder errores. Por eso es importante escribir nombres de variables claros y comprobar los valores mientras programamos.


    17. Mostrar información con echo

    echo es una de las formas más habituales de mostrar información en PHP.

    <?php

    echo "Hola mundo";

    También podemos mostrar el contenido de una variable:

    <?php

    $nombre = "Ana";

    echo $nombre;

    Y podemos combinar texto con variables:

    <?php

    $nombre = "Ana";
    $edad = 22;

    echo "Me llamo " . $nombre . " y tengo " . $edad . " años.";

    Resultado:

    Me llamo Ana y tengo 22 años.

    Cuando usamos PHP junto con HTML, echo puede generar etiquetas HTML:

    <?php

    $titulo = "Curso de PHP";

    echo "<h1>" . $titulo . "</h1>";

    El navegador recibirá:

    <h1>Curso de PHP</h1>

    Esto es útil, pero conviene no abusar de grandes bloques HTML dentro de echo, porque el código puede volverse difícil de leer.

    Por ejemplo, esto funciona:

    <?php

    $nombre = "Ana";

    echo "<div>";
    echo "<h2>Usuario</h2>";
    echo "<p>Nombre: " . $nombre . "</p>";
    echo "</div>";

    Pero muchas veces es más limpio mezclar HTML y PHP de esta manera:

    <?php
    $nombre = "Ana";
    ?>

    <div>
    <h2>Usuario</h2>
    <p>Nombre: <?php echo $nombre; ?></p>
    </div>

    Este segundo estilo suele ser más cómodo cuando estamos creando vistas o plantillas HTML.


    18. Mostrar información con print

    print es parecido a echo.

    <?php

    print "Hola mundo";

    También puede mostrar variables:

    <?php

    $nombre = "Carlos";

    print $nombre;

    En el uso diario, echo es más habitual. Para un alumno que empieza, podemos decir que ambos sirven para mostrar información, pero usaremos principalmente echo.

    Ejemplo con print:

    <?php

    $producto = "Teclado";
    $precio = 29.99;

    print "El producto " . $producto . " cuesta " . $precio . " euros.";

    Resultado:

    El producto Teclado cuesta 29.99 euros.

    19. var_dump(): ver el valor y el tipo

    var_dump() es una herramienta fundamental para aprender y depurar código PHP.

    Mientras echo muestra un valor de forma sencilla, var_dump() muestra información más detallada: el tipo de dato y el valor. La documentación oficial indica que var_dump() muestra información estructurada de una o más expresiones, incluyendo su tipo y su valor.

    Ejemplo:

    <?php

    $nombre = "Ana";
    $edad = 22;
    $precio = 19.99;
    $activo = true;

    var_dump($nombre);
    var_dump($edad);
    var_dump($precio);
    var_dump($activo);

    Resultado aproximado:

    string(3) "Ana"
    int(22)
    float(19.99)
    bool(true)

    Esto es muy útil para entender qué está pasando realmente.

    Por ejemplo, observa este caso:

    <?php

    $edad = "22";

    var_dump($edad);

    Resultado:

    string(2) "22"

    Aunque visualmente parezca un número, PHP nos está diciendo que es un texto de dos caracteres.

    Ahora mira este otro:

    <?php

    $edad = 22;

    var_dump($edad);

    Resultado:

    int(22)

    Ahora sí es un número entero.

    Esta diferencia será muy importante cuando trabajemos con formularios, porque muchos datos que llegan desde un formulario llegan inicialmente como texto.


    20. Usar <pre> con var_dump()

    Cuando usamos var_dump() en el navegador, el resultado puede verse poco ordenado, especialmente con arrays.

    Ejemplo:

    <?php

    $usuario = [
    "nombre" => "Ana",
    "email" => "ana@example.com",
    "edad" => 28
    ];

    var_dump($usuario);

    Para verlo mejor en el navegador, podemos envolver la salida con la etiqueta HTML <pre>:

    <?php

    $usuario = [
    "nombre" => "Ana",
    "email" => "ana@example.com",
    "edad" => 28
    ];

    echo "<pre>";
    var_dump($usuario);
    echo "</pre>";

    <pre> hace que el navegador respete los saltos de línea y espacios del texto. Así la salida se lee mucho mejor.

    Resultado aproximado:

    array(3) {
    ["nombre"]=>
    string(3) "Ana"
    ["email"]=>
    string(15) "ana@example.com"
    ["edad"]=>
    int(28)
    }

    Este recurso lo usaremos muchísimo durante el aprendizaje.


    21. print_r(): ver arrays de forma más simple

    print_r() también sirve para inspeccionar variables, especialmente arrays. No muestra tanta información como var_dump(), pero a veces es más fácil de leer.

    <?php

    $usuario = [
    "nombre" => "Ana",
    "email" => "ana@example.com",
    "edad" => 28
    ];

    echo "<pre>";
    print_r($usuario);
    echo "</pre>";

    Resultado aproximado:

    Array
    (
    [nombre] => Ana
    [email] => ana@example.com
    [edad] => 28
    )

    La diferencia principal es que print_r() muestra la estructura de forma más limpia, pero no indica con tanto detalle los tipos de datos.

    Comparemos:

    <?php

    $edad = "22";

    echo "<pre>";
    print_r($edad);
    echo "</pre>";

    echo "<pre>";
    var_dump($edad);
    echo "</pre>";

    print_r() mostraría algo parecido a:

    22

    var_dump() mostraría:

    string(2) "22"

    Para aprender, var_dump() suele ser mejor porque nos dice el tipo. Para revisar arrays grandes de forma rápida, print_r() puede resultar más cómodo.


    22. printf(): salida con formato

    printf() permite mostrar texto usando marcadores de posición. Es muy útil cuando queremos construir una frase con valores variables de forma más controlada.

    Ejemplo básico:

    <?php

    $nombre = "Ana";
    $edad = 22;

    printf("Me llamo %s y tengo %d años.", $nombre, $edad);

    Resultado:

    Me llamo Ana y tengo 22 años.

    Aquí aparecen dos marcadores:

    %s se usa para cadenas de texto.
    %d se usa para números enteros.

    También podemos usar %f para números decimales:

    <?php

    $producto = "Ratón";
    $precio = 15.5;

    printf("El producto %s cuesta %f euros.", $producto, $precio);

    Resultado aproximado:

    El producto Ratón cuesta 15.500000 euros.

    Como vemos, por defecto puede mostrar demasiados decimales. Podemos controlar cuántos decimales queremos:

    <?php

    $producto = "Ratón";
    $precio = 15.5;

    printf("El producto %s cuesta %.2f euros.", $producto, $precio);

    Resultado:

    El producto Ratón cuesta 15.50 euros.

    El marcador %.2f indica que queremos mostrar el número decimal con dos cifras decimales.

    Esto es muy útil para precios.

    <?php

    $precio = 19.9;
    $iva = 21;
    $total = $precio + ($precio * $iva / 100);

    printf("Precio sin IVA: %.2f €<br>", $precio);
    printf("IVA aplicado: %d %%<br>", $iva);
    printf("Precio final: %.2f €", $total);

    Resultado aproximado:

    Precio sin IVA: 19.90 €
    IVA aplicado: 21 %
    Precio final: 24.08 €

    Fíjate en este detalle:

    %d %%

    Para imprimir el símbolo % usando printf(), escribimos %%.


    23. sprintf(): guardar el texto formateado en una variable

    sprintf() se parece mucho a printf(), pero no muestra directamente el resultado. En lugar de eso, devuelve el texto formateado para que podamos guardarlo en una variable.

    <?php

    $nombre = "Ana";
    $edad = 22;

    $mensaje = sprintf("Me llamo %s y tengo %d años.", $nombre, $edad);

    echo $mensaje;

    Esto puede parecer menos directo, pero es muy útil cuando queremos preparar un mensaje antes de mostrarlo, guardarlo o enviarlo.

    Ejemplo:

    <?php

    $producto = "Teclado";
    $precio = 29.991;

    $lineaFactura = sprintf("Producto: %s - Precio: %.2f €", $producto, $precio);

    echo $lineaFactura;

    Resultado:

    Producto: Teclado - Precio: 29.99 €

    24. var_export(): mostrar una representación válida en PHP

    var_export() es otra herramienta de inspección. Se parece a var_dump(), pero tiene una diferencia interesante: genera una representación que se parece mucho a código PHP válido. La documentación oficial explica que var_export() obtiene información estructurada de una variable y que su representación es código PHP válido.

    Ejemplo:

    <?php

    $usuario = [
    "nombre" => "Ana",
    "email" => "ana@example.com",
    "edad" => 28
    ];

    echo "<pre>";
    var_export($usuario);
    echo "</pre>";

    Resultado aproximado:

    array (
    'nombre' => 'Ana',
    'email' => 'ana@example.com',
    'edad' => 28,
    )

    No es una función que necesitemos usar todo el tiempo al empezar, pero conviene conocerla. Puede ser útil cuando queremos ver una estructura de datos en un formato que luego podríamos copiar y reutilizar como código PHP.


    25. Diferencia práctica entre echo, var_dump(), print_r() y printf()

    La mejor forma de entender estas herramientas es verlas sobre el mismo dato.

    <?php

    $producto = [
    "nombre" => "Monitor",
    "precio" => 149.99,
    "stock" => 12,
    "disponible" => true
    ];

    echo "<h2>Con print_r()</h2>";
    echo "<pre>";
    print_r($producto);
    echo "</pre>";

    echo "<h2>Con var_dump()</h2>";
    echo "<pre>";
    var_dump($producto);
    echo "</pre>";

    echo "<h2>Con var_export()</h2>";
    echo "<pre>";
    var_export($producto);
    echo "</pre>";

    echo "<h2>Con printf()</h2>";
    printf(
    "El producto %s cuesta %.2f euros y tiene %d unidades en stock.",
    $producto["nombre"],
    $producto["precio"],
    $producto["stock"]
    );

    Cada herramienta tiene un propósito distinto.

    echo sirve para mostrar contenido sencillo.

    print_r() sirve para ver estructuras como arrays de forma clara.

    var_dump() sirve para ver estructura, valores y tipos de datos.

    printf() sirve para construir una salida con formato.

    var_export() sirve para ver una representación reutilizable como código PHP.

    No hay que elegir una para todo. Lo importante es saber cuándo interesa cada una.


    26. Primer ejemplo completo: datos de un alumno

    Vamos a construir un ejemplo sencillo que combine variables, tipos de datos y salida por pantalla.

    <?php

    $nombre = "Lucía";
    $apellidos = "García López";
    $edad = 21;
    $notaMedia = 8.75;
    $matriculado = true;
    $telefono = null;

    echo "<h1>Ficha del alumno</h1>";

    echo "<p>Nombre: " . $nombre . "</p>";
    echo "<p>Apellidos: " . $apellidos . "</p>";
    echo "<p>Edad: " . $edad . "</p>";

    printf("<p>Nota media: %.2f</p>", $notaMedia);

    echo "<h2>Información de depuración</h2>";
    echo "<pre>";
    var_dump($nombre);
    var_dump($apellidos);
    var_dump($edad);
    var_dump($notaMedia);
    var_dump($matriculado);
    var_dump($telefono);
    echo "</pre>";

    Este ejemplo genera una ficha sencilla en HTML, pero además nos permite inspeccionar los tipos de datos.

    Una posible salida visual sería:

    Ficha del alumno

    Nombre: Lucía
    Apellidos: García López
    Edad: 21
    Nota media: 8.75

    Y después aparecería una zona de depuración parecida a:

    string(6) "Lucía"
    string(13) "García López"
    int(21)
    float(8.75)
    bool(true)
    NULL

    Este tipo de ejemplo es perfecto para clase, porque permite ver dos cosas a la vez: lo que se muestra al usuario y lo que PHP está manejando internamente.


    27. Segundo ejemplo completo: producto de una tienda

    Ahora vamos a usar un ejemplo más cercano a una aplicación web real: un producto de una tienda.

    <?php

    $nombreProducto = "Auriculares Bluetooth";
    $categoria = "Sonido";
    $precio = 39.99;
    $unidadesDisponibles = 15;
    $tieneDescuento = true;
    $porcentajeDescuento = 10;

    $precioFinal = $precio;

    if ($tieneDescuento) {
    $precioFinal = $precio - ($precio * $porcentajeDescuento / 100);
    }

    echo "<h1>Detalle del producto</h1>";

    echo "<p>Producto: " . $nombreProducto . "</p>";
    echo "<p>Categoría: " . $categoria . "</p>";

    printf("<p>Precio original: %.2f €</p>", $precio);

    if ($tieneDescuento) {
    echo "<p>Descuento aplicado: " . $porcentajeDescuento . "%</p>";
    }

    printf("<p>Precio final: %.2f €</p>", $precioFinal);

    echo "<p>Unidades disponibles: " . $unidadesDisponibles . "</p>";

    echo "<h2>Depuración</h2>";
    echo "<pre>";
    var_dump($nombreProducto);
    var_dump($categoria);
    var_dump($precio);
    var_dump($unidadesDisponibles);
    var_dump($tieneDescuento);
    var_dump($porcentajeDescuento);
    var_dump($precioFinal);
    echo "</pre>";

    Aunque todavía no hayamos estudiado condiciones en profundidad, el ejemplo se entiende bastante bien. Tenemos un producto, un precio, un descuento y un cálculo final.

    Este ejemplo también muestra por qué los tipos de datos importan:

    $nombreProducto es texto.
    $precio es decimal.
    $unidadesDisponibles es entero.
    $tieneDescuento es booleano.
    $precioFinal se calcula a partir de otros valores.


    28. Errores frecuentes al empezar con PHP

    Uno de los errores más comunes es olvidar el punto y coma:

    <?php

    $nombre = "Ana"
    echo $nombre;

    La forma correcta es:

    <?php

    $nombre = "Ana";
    echo $nombre;

    Otro error muy común es olvidar el símbolo $ delante de una variable:

    <?php

    nombre = "Ana";

    La forma correcta es:

    <?php

    $nombre = "Ana";

    También es frecuente mezclar mal las comillas:

    <?php

    echo "Hola mundo';

    La forma correcta sería:

    <?php

    echo "Hola mundo";

    O también:

    <?php

    echo 'Hola mundo';

    Otro error habitual aparece al concatenar:

    <?php

    $nombre = "Ana";

    echo "Hola " $nombre;

    La forma correcta es usar el punto:

    <?php

    $nombre = "Ana";

    echo "Hola " . $nombre;

    También podemos usar comillas dobles con la variable dentro:

    <?php

    $nombre = "Ana";

    echo "Hola $nombre";

    Pero al principio recomiendo practicar bastante la concatenación con . porque ayuda a entender mejor cómo se construyen las cadenas.


    29. Buenas prácticas desde el primer día

    Aunque estemos empezando, conviene adquirir buenas costumbres desde el principio.

    Una buena práctica es usar nombres de variables descriptivos:

    $precioProducto = 29.99;
    $nombreUsuario = "ana";
    $usuarioActivo = true;

    Es peor escribir:

    $p = 29.99;
    $n = "ana";
    $u = true;

    Otra buena práctica es separar el código para que se lea bien:

    <?php

    $precio = 100;
    $iva = 21;

    $total = $precio + ($precio * $iva / 100);

    echo $total;

    Es mejor que escribirlo todo apelotonado:

    <?php
    $precio=100;$iva=21;$total=$precio+($precio*$iva/100);echo $total;

    También es buena idea usar var_dump() durante el aprendizaje. No debemos verlo como algo “de novatos”, sino como una herramienta de trabajo. Programar no consiste en adivinar qué está pasando. Programar consiste en comprobarlo.


    30. Ejercicio guiado para el alumno

    Crea un archivo llamado:

    tema1_sintaxis.php

    Dentro del archivo, crea una pequeña ficha personal usando variables.

    Debe tener los siguientes datos:

    Nombre.
    Edad.
    Ciudad.
    Curso.
    Nota media.
    Si está matriculado o no.
    Un dato opcional con valor null, por ejemplo, segundo teléfono.

    Después, muestra la información en HTML usando echo y printf().

    Finalmente, muestra una zona de depuración usando var_dump().

    Una posible solución sería:

    <?php

    $nombre = "Mario";
    $edad = 24;
    $ciudad = "Madrid";
    $curso = "Programación con PHP";
    $notaMedia = 8.25;
    $matriculado = true;
    $segundoTelefono = null;

    echo "<h1>Ficha del estudiante</h1>";

    echo "<p>Nombre: " . $nombre . "</p>";
    echo "<p>Edad: " . $edad . " años</p>";
    echo "<p>Ciudad: " . $ciudad . "</p>";
    echo "<p>Curso: " . $curso . "</p>";

    printf("<p>Nota media: %.2f</p>", $notaMedia);

    echo "<h2>Estado de matrícula</h2>";

    if ($matriculado) {
    echo "<p>El alumno está matriculado.</p>";
    } else {
    echo "<p>El alumno no está matriculado.</p>";
    }

    echo "<h2>Depuración de variables</h2>";

    echo "<pre>";
    var_dump($nombre);
    var_dump($edad);
    var_dump($ciudad);
    var_dump($curso);
    var_dump($notaMedia);
    var_dump($matriculado);
    var_dump($segundoTelefono);
    echo "</pre>";

    Este ejercicio es sencillo, pero toca varios puntos importantes: creación de variables, tipos de datos, salida HTML, formato numérico y depuración.


    31. Ejercicio propuesto: ficha de producto

    Crea un archivo llamado:

    producto.php

    Define las siguientes variables:

    Nombre del producto.
    Categoría.
    Precio.
    Unidades en stock.
    Si está disponible o no.
    Descuento aplicado.

    Después muestra una ficha del producto en HTML.

    El precio debe mostrarse con dos decimales usando printf().

    Al final, muestra todas las variables con var_dump() dentro de una etiqueta <pre>.

    Una posible base sería:

    <?php

    $nombreProducto = "Teclado mecánico";
    $categoria = "Informática";
    $precio = 59.95;
    $stock = 8;
    $disponible = true;
    $descuento = 15;

    echo "<h1>Producto</h1>";

    // Continúa el ejercicio aquí

    El objetivo no es solo que funcione. El objetivo es que el código se entienda.


    32. Resumen final

    En este tema hemos visto la base de la sintaxis de PHP. Ya sabemos que el código PHP se escribe dentro de bloques que empiezan normalmente con <?php. También hemos visto que las instrucciones suelen terminar con punto y coma y que los comentarios nos permiten documentar el código sin que PHP los ejecute.

    Hemos aprendido que las variables en PHP empiezan con $ y que pueden guardar diferentes tipos de datos: textos, enteros, decimales, booleanos, valores nulos y arrays. También hemos visto que PHP es flexible con los tipos, pero que precisamente por eso debemos ser ordenados y claros al escribir nuestras variables.

    Por último, hemos trabajado varias herramientas de salida. echo nos permite mostrar contenido sencillo. print es parecido, aunque lo usaremos menos. var_dump() nos muestra el tipo y el valor de una variable, lo que lo convierte en una herramienta excelente para aprender y depurar. print_r() resulta cómodo para ver arrays. printf() nos permite mostrar textos con formato, especialmente útil para números y precios. Y var_export() nos ofrece una representación más cercana a código PHP reutilizable.

    A partir de aquí ya podemos empezar a escribir pequeños scripts PHP con sentido. Todavía son programas sencillos, pero esta base es imprescindible. Si el alumno domina bien variables, tipos y salida por pantalla, tendrá mucho más fácil entender condiciones, bucles, funciones, formularios y bases de datos en los siguientes temas.

  • 1.7 – Estructuras de control

    1.7 – Estructuras de control

    Hasta ahora hemos visto cómo escribir nuestros primeros scripts en PHP, cómo crear variables, cómo mostrar información en pantalla y cómo trabajar con distintos tipos de datos. Todo eso nos permite guardar y enseñar información, pero todavía nos falta algo fundamental: hacer que el programa tome decisiones.

    Un programa real no ejecuta siempre las mismas instrucciones de forma lineal. A veces debe comprobar una condición y actuar de una manera u otra. Por ejemplo:

    • Un usuario puede ser mayor o menor de edad.
    • Una contraseña puede ser correcta o incorrecta.
    • Un producto puede tener stock o estar agotado.
    • Una nota puede estar aprobada o suspensa.
    • Un usuario puede ser administrador o cliente normal.

    Para resolver este tipo de situaciones utilizamos condicionales.

    En PHP, igual que en muchos otros lenguajes de programación, las estructuras condicionales nos permiten ejecutar un bloque de código solamente si se cumple una condición.


    1. ¿Qué es una condición?

    Una condición es una expresión que PHP puede evaluar como verdadera o falsa.

    Por ejemplo:

    $edad = 20;

    $edad >= 18

    La expresión anterior comprueba si la variable $edad es mayor o igual que 18.

    Como $edad vale 20, la condición se cumple. Es decir, PHP la considera verdadera.

    Si cambiamos el valor:

    $edad = 15;

    $edad >= 18

    Ahora la condición no se cumple, porque 15 no es mayor o igual que 18.

    Cuando trabajamos con condicionales, PHP evalúa expresiones que normalmente devuelven un valor booleano:

    true
    false

    Aunque en PHP también hay valores que pueden comportarse como verdaderos o falsos, como veremos más adelante.


    2. El condicional if

    La estructura condicional más básica es if.

    Su traducción sería:

    Si se cumple esta condición, ejecuta este bloque de código.

    La estructura general es:

    if (condicion) {
    // Código que se ejecuta si la condición es verdadera
    }

    Ejemplo básico:

    <?php

    $edad = 20;

    if ($edad >= 18) {
    echo "Eres mayor de edad.";
    }

    ?>

    En este caso, como $edad vale 20, la condición $edad >= 18 se cumple y se mostrará el mensaje:

    Eres mayor de edad.

    Si cambiamos la edad:

    <?php

    $edad = 15;

    if ($edad >= 18) {
    echo "Eres mayor de edad.";
    }

    ?>

    No se mostrará nada, porque la condición no se cumple.

    Esto es importante: si la condición de un if no se cumple, PHP ignora el bloque de código que está dentro de las llaves.


    3. Ejemplo práctico: comprobar una nota

    Vamos a imaginar que estamos creando una pequeña aplicación para mostrar si un alumno ha aprobado.

    <?php

    $nota = 7;

    if ($nota >= 5) {
    echo "Has aprobado.";
    }

    ?>

    Como la nota es 7, se muestra:

    Has aprobado.

    Pero si la nota fuese un 3, no aparecería ningún mensaje. Eso no es muy útil para el usuario, porque si ha suspendido también deberíamos informarle.

    Para eso usamos else.


    4. El condicional if...else

    La estructura if...else permite ejecutar un bloque de código cuando la condición se cumple y otro bloque diferente cuando no se cumple.

    Su traducción sería:

    Si se cumple esta condición, haz esto. Si no se cumple, haz esto otro.

    Estructura general:

    if (condicion) {
    // Código si la condición es verdadera
    } else {
    // Código si la condición es falsa
    }

    Ejemplo:

    <?php

    $nota = 3;

    if ($nota >= 5) {
    echo "Has aprobado.";
    } else {
    echo "Has suspendido.";
    }

    ?>

    En este caso, como $nota vale 3, la condición $nota >= 5 no se cumple. Por tanto, PHP ejecuta el bloque del else.

    Resultado:

    Has suspendido.

    Ahora el programa ya responde en los dos casos posibles.


    5. Ejemplo práctico: acceso por edad

    Imaginemos una web donde solo pueden acceder personas mayores de edad.

    <?php

    $edad = 17;

    if ($edad >= 18) {
    echo "Puedes acceder al contenido.";
    } else {
    echo "No puedes acceder. Debes ser mayor de edad.";
    }

    ?>

    Este tipo de comprobación es muy habitual en aplicaciones web. PHP recibe un dato, lo comprueba y decide qué respuesta debe mostrar.

    Podríamos mejorar el mensaje usando la propia edad del usuario:

    <?php

    $edad = 17;

    if ($edad >= 18) {
    echo "Tienes $edad años. Puedes acceder al contenido.";
    } else {
    echo "Tienes $edad años. No puedes acceder todavía.";
    }

    ?>

    Resultado:

    Tienes 17 años. No puedes acceder todavía.

    6. Operadores de comparación

    Para crear condiciones necesitamos comparar valores. PHP dispone de varios operadores de comparación.

    Los más utilizados son:

    OperadorSignificadoEjemplo
    ==Igual en valor$a == $b
    ===Igual en valor y tipo$a === $b
    !=Distinto en valor$a != $b
    !==Distinto en valor o tipo$a !== $b
    >Mayor que$a > $b
    <Menor que$a < $b
    >=Mayor o igual que$a >= $b
    <=Menor o igual que$a <= $b

    Vamos a verlo con ejemplos.

    <?php

    $numero = 10;

    if ($numero > 5) {
    echo "El número es mayor que 5.";
    }

    ?>

    Aquí la condición se cumple porque 10 es mayor que 5.

    Otro ejemplo:

    <?php

    $usuario = "admin";

    if ($usuario == "admin") {
    echo "Bienvenido, administrador.";
    }

    ?>

    La condición se cumple porque el contenido de $usuario es igual a "admin".


    7. Diferencia entre == y ===

    Este punto es muy importante en PHP.

    El operador == compara si dos valores son iguales, pero puede hacer conversiones automáticas de tipo.

    El operador === compara si dos valores son iguales y además son del mismo tipo.

    Ejemplo:

    <?php

    $numero = 5;
    $texto = "5";

    if ($numero == $texto) {
    echo "Son iguales usando ==.";
    }

    ?>

    Este código muestra:

    Son iguales usando ==.

    PHP considera que 5 y "5" son iguales en valor, aunque uno sea un número entero y el otro sea una cadena de texto.

    Ahora usamos ===:

    <?php

    $numero = 5;
    $texto = "5";

    if ($numero === $texto) {
    echo "Son iguales usando ===.";
    } else {
    echo "No son exactamente iguales.";
    }

    ?>

    Resultado:

    No son exactamente iguales.

    ¿Por qué? Porque $numero es un entero y $texto es una cadena.

    En programación real, especialmente cuando trabajemos con formularios, bases de datos y sesiones, conviene acostumbrarse a usar === cuando queramos comprobar igualdad estricta.


    8. Ejemplo práctico: comprobar usuario y contraseña

    Vamos a simular un inicio de sesión muy sencillo.

    <?php

    $usuario = "antonio";
    $password = "1234";

    if ($usuario === "antonio" && $password === "1234") {
    echo "Acceso permitido.";
    } else {
    echo "Usuario o contraseña incorrectos.";
    }

    ?>

    Aquí aparecen dos condiciones al mismo tiempo:

    $usuario === "antonio"

    y

    $password === "1234"

    Para que el acceso sea permitido, ambas deben cumplirse.

    Para unir condiciones usamos operadores lógicos.


    9. Operadores lógicos

    Los operadores lógicos permiten combinar varias condiciones.

    Los principales son:

    OperadorNombreSignificado
    &&ANDSe cumplen todas las condiciones
    ``
    !NOTNiega una condición

    Aunque PHP también permite escribir and y or, en este nivel es recomendable usar && y ||, porque son más habituales y evitan algunos problemas de prioridad.


    10. Uso de &&: todas las condiciones deben cumplirse

    El operador && significa “y”.

    Se utiliza cuando necesitamos que se cumplan varias condiciones a la vez.

    Ejemplo:

    <?php

    $edad = 22;
    $tieneEntrada = true;

    if ($edad >= 18 && $tieneEntrada === true) {
    echo "Puedes entrar al evento.";
    } else {
    echo "No puedes entrar al evento.";
    }

    ?>

    Para poder entrar al evento deben cumplirse dos cosas:

    La persona debe tener al menos 18 años.
    La persona debe tener entrada.

    Si una de las dos falla, el resultado será negativo.

    Podemos escribirlo también de forma un poco más natural:

    <?php

    $edad = 22;
    $tieneEntrada = true;

    if ($edad >= 18 && $tieneEntrada) {
    echo "Puedes entrar al evento.";
    } else {
    echo "No puedes entrar al evento.";
    }

    ?>

    Cuando una variable ya contiene true o false, no siempre es necesario compararla con true.


    11. Uso de ||: basta con que se cumpla una condición

    El operador || significa “o”.

    Se utiliza cuando basta con que se cumpla una de varias condiciones.

    Ejemplo:

    <?php

    $rol = "editor";

    if ($rol === "admin" || $rol === "editor") {
    echo "Puedes acceder al panel de gestión.";
    } else {
    echo "No tienes permisos para acceder.";
    }

    ?>

    En este caso, el usuario puede acceder si su rol es "admin" o si su rol es "editor".

    Como $rol vale "editor", la condición se cumple.

    Este tipo de comprobación se usa mucho en aplicaciones web con distintos tipos de usuario.


    12. Uso de !: negar una condición

    El operador ! sirve para negar una condición.

    Es decir, convierte true en false y false en true.

    Ejemplo:

    <?php

    $sesionIniciada = false;

    if (!$sesionIniciada) {
    echo "Debes iniciar sesión para continuar.";
    }

    ?>

    La variable $sesionIniciada vale false.

    Al escribir:

    !$sesionIniciada

    Estamos diciendo:

    Si NO hay sesión iniciada…

    Por eso se muestra el mensaje.

    Otro ejemplo:

    <?php

    $productoDisponible = false;

    if (!$productoDisponible) {
    echo "El producto no está disponible.";
    } else {
    echo "Puedes comprar el producto.";
    }

    ?>

    13. elseif: comprobar varias posibilidades

    A veces no tenemos solo dos caminos posibles.

    Por ejemplo, una nota no es simplemente aprobado o suspenso. También podemos querer distinguir entre suspenso, aprobado, notable y sobresaliente.

    Para eso usamos elseif.

    La estructura general es:

    if (condicion1) {
    // Código si se cumple la primera condición
    } elseif (condicion2) {
    // Código si no se cumple la primera, pero sí la segunda
    } elseif (condicion3) {
    // Código si se cumple la tercera
    } else {
    // Código si no se cumple ninguna de las anteriores
    }

    Ejemplo:

    <?php

    $nota = 8;

    if ($nota < 5) {
    echo "Suspenso.";
    } elseif ($nota < 7) {
    echo "Aprobado.";
    } elseif ($nota < 9) {
    echo "Notable.";
    } else {
    echo "Sobresaliente.";
    }

    ?>

    Resultado:

    Notable.

    Es importante entender cómo lee PHP este bloque:

    Primero comprueba si $nota < 5.
    Como 8 < 5 es falso, pasa al siguiente.
    Después comprueba si $nota < 7.
    Como 8 < 7 es falso, pasa al siguiente.
    Después comprueba si $nota < 9.
    Como 8 < 9 es verdadero, ejecuta ese bloque y ya no sigue comprobando más.

    Por eso muestra "Notable.".


    14. Cuidado con el orden de las condiciones

    El orden de las condiciones importa muchísimo.

    Imagina este ejemplo incorrecto:

    <?php

    $nota = 8;

    if ($nota >= 5) {
    echo "Aprobado.";
    } elseif ($nota >= 7) {
    echo "Notable.";
    } elseif ($nota >= 9) {
    echo "Sobresaliente.";
    } else {
    echo "Suspenso.";
    }

    ?>

    Aunque la nota sea 8, el programa mostrará:

    Aprobado.

    ¿Por qué?

    Porque la primera condición $nota >= 5 ya se cumple. PHP entra en ese bloque y no sigue comprobando los demás elseif.

    Para corregirlo, deberíamos empezar por las notas más altas:

    <?php

    $nota = 8;

    if ($nota >= 9) {
    echo "Sobresaliente.";
    } elseif ($nota >= 7) {
    echo "Notable.";
    } elseif ($nota >= 5) {
    echo "Aprobado.";
    } else {
    echo "Suspenso.";
    }

    ?>

    Ahora sí se mostrará:

    Notable.

    Esta idea es fundamental: en una cadena de if, elseif y else, PHP ejecuta el primer bloque cuya condición sea verdadera.


    15. Ejemplo práctico completo: sistema de notas

    Vamos a crear un ejemplo algo más completo. Queremos mostrar la calificación de un alumno, pero también controlar que la nota sea válida.

    Una nota válida debería estar entre 0 y 10.

    <?php

    $nota = 11;

    if ($nota < 0 || $nota > 10) {
    echo "La nota introducida no es válida.";
    } elseif ($nota >= 9) {
    echo "Sobresaliente.";
    } elseif ($nota >= 7) {
    echo "Notable.";
    } elseif ($nota >= 5) {
    echo "Aprobado.";
    } else {
    echo "Suspenso.";
    }

    ?>

    En este caso, como la nota es 11, mostramos:

    La nota introducida no es válida.

    La primera condición comprueba si la nota está fuera del rango permitido:

    $nota < 0 || $nota > 10

    Es decir:

    Si la nota es menor que 0 o mayor que 10, no es válida.

    Este tipo de validaciones son muy habituales en aplicaciones reales. No basta con procesar los datos; primero debemos comprobar que tienen sentido.


    16. Condicionales anidados

    Un condicional anidado es un if dentro de otro if.

    Se utiliza cuando una decisión depende de otra decisión anterior.

    Ejemplo:

    <?php

    $usuario = "antonio";
    $password = "1234";
    $cuentaActiva = true;

    if ($usuario === "antonio" && $password === "1234") {
    if ($cuentaActiva) {
    echo "Bienvenido al sistema.";
    } else {
    echo "Tu cuenta está desactivada.";
    }
    } else {
    echo "Usuario o contraseña incorrectos.";
    }

    ?>

    Aquí primero comprobamos si el usuario y la contraseña son correctos.

    Solo si son correctos, comprobamos después si la cuenta está activa.

    Esto tiene sentido porque no necesitamos comprobar si la cuenta está activa cuando el usuario ni siquiera se ha identificado correctamente.

    Sin embargo, hay que tener cuidado. Si anidamos demasiados condicionales, el código puede volverse difícil de leer.


    17. Mejorando la lectura de condicionales

    Observa este código:

    <?php

    $edad = 20;
    $tieneEntrada = true;
    $estaVetado = false;

    if ($edad >= 18) {
    if ($tieneEntrada) {
    if (!$estaVetado) {
    echo "Puedes entrar.";
    } else {
    echo "No puedes entrar porque estás vetado.";
    }
    } else {
    echo "No puedes entrar porque no tienes entrada.";
    }
    } else {
    echo "No puedes entrar porque eres menor de edad.";
    }

    ?>

    Funciona, pero empieza a ser incómodo.

    Podemos escribirlo de una forma más clara usando varias condiciones:

    <?php

    $edad = 20;
    $tieneEntrada = true;
    $estaVetado = false;

    if ($edad < 18) {
    echo "No puedes entrar porque eres menor de edad.";
    } elseif (!$tieneEntrada) {
    echo "No puedes entrar porque no tienes entrada.";
    } elseif ($estaVetado) {
    echo "No puedes entrar porque estás vetado.";
    } else {
    echo "Puedes entrar.";
    }

    ?>

    Este segundo código suele ser más fácil de leer porque va descartando casos.

    Primero mira si la edad no es válida.
    Después mira si no tiene entrada.
    Después mira si está vetado.
    Y si no ocurre nada de eso, permite entrar.

    Este estilo será muy útil cuando empecemos a validar formularios.


    18. Condicionales con cadenas de texto

    Los condicionales no solo sirven para números. También podemos comparar cadenas de texto.

    Ejemplo:

    <?php

    $dia = "lunes";

    if ($dia === "lunes") {
    echo "Hoy empieza la semana.";
    } else {
    echo "Hoy no es lunes.";
    }

    ?>

    Otro ejemplo:

    <?php

    $estadoPedido = "pendiente";

    if ($estadoPedido === "pendiente") {
    echo "Tu pedido está pendiente de preparación.";
    } elseif ($estadoPedido === "enviado") {
    echo "Tu pedido ya ha sido enviado.";
    } elseif ($estadoPedido === "entregado") {
    echo "Tu pedido ha sido entregado.";
    } else {
    echo "Estado del pedido desconocido.";
    }

    ?>

    Este ejemplo se parece más a una situación real. Muchas aplicaciones trabajan con estados: usuarios activos o inactivos, pedidos pendientes, reservas aceptadas, productos agotados, pagos confirmados, etc.


    19. Ejemplo práctico: estado de una reserva

    Imaginemos que estamos desarrollando una aplicación de reservas.

    Una reserva puede estar en distintos estados:

    pendiente, aceptada, cancelada o finalizada.

    <?php

    $estadoReserva = "pendiente";

    if ($estadoReserva === "pendiente") {
    echo "La reserva está pendiente de confirmación.";
    } elseif ($estadoReserva === "aceptada") {
    echo "La reserva ha sido aceptada.";
    } elseif ($estadoReserva === "cancelada") {
    echo "La reserva ha sido cancelada.";
    } elseif ($estadoReserva === "finalizada") {
    echo "La reserva ya ha finalizado.";
    } else {
    echo "El estado de la reserva no es válido.";
    }

    ?>

    Este tipo de estructura se usará mucho cuando trabajemos con bases de datos. Por ejemplo, podemos guardar en una tabla el estado de una reserva y después mostrar un mensaje diferente según ese estado.


    20. La estructura switch

    Cuando tenemos que comparar una misma variable con muchos valores posibles, podemos usar switch.

    Por ejemplo, este código con if funciona perfectamente:

    <?php

    $dia = "martes";

    if ($dia === "lunes") {
    echo "Inicio de semana.";
    } elseif ($dia === "martes") {
    echo "Segundo día de la semana.";
    } elseif ($dia === "miércoles") {
    echo "Mitad de semana.";
    } elseif ($dia === "jueves") {
    echo "Casi viernes.";
    } elseif ($dia === "viernes") {
    echo "Último día laboral.";
    } else {
    echo "Fin de semana o día no reconocido.";
    }

    ?>

    Pero también podemos escribirlo con switch:

    <?php

    $dia = "martes";

    switch ($dia) {
    case "lunes":
    echo "Inicio de semana.";
    break;

    case "martes":
    echo "Segundo día de la semana.";
    break;

    case "miércoles":
    echo "Mitad de semana.";
    break;

    case "jueves":
    echo "Casi viernes.";
    break;

    case "viernes":
    echo "Último día laboral.";
    break;

    default:
    echo "Fin de semana o día no reconocido.";
    break;
    }

    ?>

    El switch compara el valor de $dia con cada uno de los case.

    Cuando encuentra una coincidencia, ejecuta el código correspondiente.

    El default se ejecuta si no coincide con ningún case.


    21. La importancia de break en switch

    En un switch, normalmente escribimos break al final de cada case.

    El break sirve para salir del switch.

    Si olvidamos el break, PHP puede seguir ejecutando los siguientes casos aunque no correspondan.

    Ejemplo problemático:

    <?php

    $rol = "editor";

    switch ($rol) {
    case "admin":
    echo "Acceso total.";

    case "editor":
    echo "Acceso a edición.";

    case "cliente":
    echo "Acceso a compras.";

    default:
    echo "Rol desconocido.";
    }

    ?>

    Si $rol vale "editor", PHP entra en el caso "editor", pero como no hay break, seguirá ejecutando también los bloques siguientes.

    Por eso deberíamos escribirlo así:

    <?php

    $rol = "editor";

    switch ($rol) {
    case "admin":
    echo "Acceso total.";
    break;

    case "editor":
    echo "Acceso a edición.";
    break;

    case "cliente":
    echo "Acceso a compras.";
    break;

    default:
    echo "Rol desconocido.";
    break;
    }

    ?>

    22. Ejemplo práctico con switch: menú de opciones

    Imaginemos que tenemos una variable que representa la opción seleccionada por un usuario en un menú.

    <?php

    $opcion = 2;

    switch ($opcion) {
    case 1:
    echo "Has seleccionado ver productos.";
    break;

    case 2:
    echo "Has seleccionado ver el carrito.";
    break;

    case 3:
    echo "Has seleccionado finalizar compra.";
    break;

    case 4:
    echo "Has seleccionado salir.";
    break;

    default:
    echo "Opción no válida.";
    break;
    }

    ?>

    Este tipo de estructura es útil cuando estamos gestionando opciones cerradas y conocidas.


    23. match: una alternativa moderna a switch

    En versiones modernas de PHP existe también la expresión match.

    Se parece a switch, pero tiene algunas diferencias importantes:

    • match devuelve un valor.
    • No necesita break.
    • Compara de forma estricta.
    • Suele ser más compacto.

    Ejemplo:

    <?php

    $estadoPedido = "enviado";

    $mensaje = match ($estadoPedido) {
    "pendiente" => "Tu pedido está pendiente.",
    "enviado" => "Tu pedido ha sido enviado.",
    "entregado" => "Tu pedido ha sido entregado.",
    "cancelado" => "Tu pedido ha sido cancelado.",
    default => "Estado desconocido.",
    };

    echo $mensaje;

    ?>

    Resultado:

    Tu pedido ha sido enviado.

    match es muy útil cuando queremos asignar un valor dependiendo de otro.

    Otro ejemplo:

    <?php

    $rol = "admin";

    $permisos = match ($rol) {
    "admin" => "Acceso total",
    "editor" => "Puede editar contenido",
    "cliente" => "Puede hacer compras",
    default => "Sin permisos especiales",
    };

    echo $permisos;

    ?>

    Aunque match es muy cómodo, para empezar conviene dominar primero if, else, elseif y switch, porque aparecen en muchísimos ejemplos y proyectos.


    24. El operador ternario

    El operador ternario permite escribir un if...else sencillo en una sola línea.

    Su estructura es:

    condicion ? valor_si_verdadero : valor_si_falso;

    Ejemplo con if...else normal:

    <?php

    $edad = 20;

    if ($edad >= 18) {
    $mensaje = "Mayor de edad";
    } else {
    $mensaje = "Menor de edad";
    }

    echo $mensaje;

    ?>

    El mismo ejemplo con operador ternario:

    <?php

    $edad = 20;

    $mensaje = $edad >= 18 ? "Mayor de edad" : "Menor de edad";

    echo $mensaje;

    ?>

    Resultado:

    Mayor de edad

    El ternario es útil para condiciones pequeñas, pero no conviene abusar de él. Si la condición es compleja, un if...else normal suele ser más claro.

    Ejemplo práctico:

    <?php

    $stock = 0;

    $mensaje = $stock > 0 ? "Producto disponible" : "Producto agotado";

    echo $mensaje;

    ?>

    25. El operador de fusión de null: ??

    En PHP también existe el operador ??, llamado operador de fusión de null.

    Sirve para usar un valor alternativo cuando una variable no existe o vale null.

    Esto será muy útil cuando trabajemos con formularios.

    Ejemplo:

    <?php

    $nombre = $_GET["nombre"] ?? "Invitado";

    echo "Hola, $nombre";

    ?>

    Este código intenta leer el parámetro nombre desde la URL.

    Por ejemplo:

    pagina.php?nombre=Antonio

    En ese caso, mostrará:

    Hola, Antonio

    Pero si no existe nombre en la URL, usará "Invitado".

    Sin ??, podríamos tener errores o avisos si intentamos acceder a una variable que no existe.


    26. Condicionales con formularios

    Uno de los usos más importantes de los condicionales en PHP es validar datos recibidos desde formularios HTML.

    Vamos a crear un ejemplo sencillo.

    Archivo formulario.html:

    <form action="procesar.php" method="post">
    <label for="nombre">Nombre:</label>
    <input type="text" name="nombre" id="nombre">

    <button type="submit">Enviar</button>
    </form>

    Archivo procesar.php:

    <?php

    $nombre = $_POST["nombre"] ?? "";

    if ($nombre === "") {
    echo "Debes escribir tu nombre.";
    } else {
    echo "Hola, $nombre.";
    }

    ?>

    Aquí usamos:

    $_POST["nombre"] ?? ""

    para recoger el valor enviado desde el formulario.

    Después comprobamos si está vacío:

    if ($nombre === "")

    Si no hay nombre, mostramos un mensaje de error.
    Si hay nombre, saludamos al usuario.


    27. Validar varios campos de un formulario

    Vamos a ampliar el ejemplo anterior con nombre, edad y email.

    Formulario:

    <form action="procesar.php" method="post">
    <label for="nombre">Nombre:</label>
    <input type="text" name="nombre" id="nombre">

    <br><br>

    <label for="edad">Edad:</label>
    <input type="number" name="edad" id="edad">

    <br><br>

    <label for="email">Email:</label>
    <input type="email" name="email" id="email">

    <br><br>

    <button type="submit">Enviar</button>
    </form>

    Archivo procesar.php:

    <?php

    $nombre = $_POST["nombre"] ?? "";
    $edad = $_POST["edad"] ?? "";
    $email = $_POST["email"] ?? "";

    if ($nombre === "") {
    echo "El nombre es obligatorio.";
    } elseif ($edad === "") {
    echo "La edad es obligatoria.";
    } elseif ($email === "") {
    echo "El email es obligatorio.";
    } elseif ($edad < 18) {
    echo "Debes ser mayor de edad para registrarte.";
    } else {
    echo "Registro correcto.";
    }

    ?>

    Este ejemplo ya se parece mucho más a una validación real.

    Primero comprobamos que los campos obligatorios no estén vacíos.
    Después comprobamos una regla concreta: que la edad sea mayor o igual que 18.
    Finalmente, si todo está bien, mostramos el mensaje de registro correcto.


    28. Mejorando la validación de edad

    Hay un detalle importante. Los datos que llegan desde un formulario suelen llegar como texto, aunque el input sea de tipo number.

    Por eso conviene validar bien.

    <?php

    $edad = $_POST["edad"] ?? "";

    if ($edad === "") {
    echo "La edad es obligatoria.";
    } elseif (!is_numeric($edad)) {
    echo "La edad debe ser un número.";
    } elseif ($edad < 0 || $edad > 120) {
    echo "La edad no parece válida.";
    } elseif ($edad < 18) {
    echo "Debes ser mayor de edad.";
    } else {
    echo "Edad correcta.";
    }

    ?>

    Aquí aparece una función nueva:

    is_numeric($edad)

    Esta función comprueba si un valor es numérico.

    El operador ! delante significa “no”.

    Por tanto:

    !is_numeric($edad)

    significa:

    Si la edad no es numérica…

    Este tipo de validación es esencial. Nunca debemos confiar ciegamente en los datos que llegan desde un formulario.


    29. Condicionales y arrays

    Aunque los arrays se estudiarán con más detalle más adelante, podemos ver ya un ejemplo sencillo.

    Imaginemos que tenemos un array con productos:

    <?php

    $productos = ["teclado", "ratón", "monitor"];

    $productoBuscado = "ratón";

    if (in_array($productoBuscado, $productos)) {
    echo "El producto está disponible.";
    } else {
    echo "El producto no está disponible.";
    }

    ?>

    La función in_array() comprueba si un valor existe dentro de un array.

    En este caso, "ratón" sí está dentro del array, por lo que se muestra:

    El producto está disponible.

    Ejemplo aplicado a roles:

    <?php

    $rolesPermitidos = ["admin", "editor"];
    $rolUsuario = "cliente";

    if (in_array($rolUsuario, $rolesPermitidos)) {
    echo "Puedes acceder al panel.";
    } else {
    echo "No tienes permisos.";
    }

    ?>

    Este ejemplo es más flexible que escribir:

    $rolUsuario === "admin" || $rolUsuario === "editor"

    Cuando hay muchos valores posibles, usar un array puede ser más cómodo.


    30. Condicionales con fechas

    PHP también puede trabajar con fechas y tomar decisiones según el día actual.

    Ejemplo:

    <?php

    $hora = date("H");

    if ($hora < 12) {
    echo "Buenos días.";
    } elseif ($hora < 20) {
    echo "Buenas tardes.";
    } else {
    echo "Buenas noches.";
    }

    ?>

    La función date("H") devuelve la hora actual en formato de 24 horas.

    Si la hora es menor que 12, mostramos "Buenos días".
    Si no, pero es menor que 20, mostramos "Buenas tardes".
    En cualquier otro caso, mostramos "Buenas noches".

    Este tipo de condicional puede usarse en una web para personalizar mensajes según la hora.


    31. Valores que PHP interpreta como falso

    En PHP no solamente false se considera falso.

    También hay otros valores que, en una condición, PHP puede interpretar como falsos.

    Algunos de los más importantes son:

    ValorPHP lo interpreta como
    falsefalso
    0falso
    "0"falso
    ""falso
    nullfalso
    []falso

    Ejemplo:

    <?php

    $nombre = "";

    if ($nombre) {
    echo "El nombre tiene contenido.";
    } else {
    echo "El nombre está vacío.";
    }

    ?>

    Como $nombre contiene una cadena vacía, PHP la interpreta como falso.

    Resultado:

    El nombre está vacío.

    Sin embargo, para alumnos que están empezando, muchas veces es más claro escribir condiciones explícitas:

    <?php

    $nombre = "";

    if ($nombre !== "") {
    echo "El nombre tiene contenido.";
    } else {
    echo "El nombre está vacío.";
    }

    ?>

    Este segundo ejemplo deja más claro qué estamos comprobando.


    32. Ejemplo práctico completo: acceso a una zona privada

    Vamos a unir varias ideas en un ejemplo más completo.

    Queremos comprobar:

    El usuario debe haber iniciado sesión.
    La cuenta debe estar activa.
    El rol debe ser admin o editor.

    <?php

    $sesionIniciada = true;
    $cuentaActiva = true;
    $rol = "editor";

    if (!$sesionIniciada) {
    echo "Debes iniciar sesión.";
    } elseif (!$cuentaActiva) {
    echo "Tu cuenta no está activa.";
    } elseif ($rol === "admin" || $rol === "editor") {
    echo "Puedes acceder a la zona privada.";
    } else {
    echo "No tienes permisos suficientes.";
    }

    ?>

    Este código está escrito de forma ordenada.

    Primero comprobamos los errores principales:

    Si no hay sesión, no dejamos continuar.
    Si la cuenta no está activa, tampoco.
    Si todo lo anterior está bien, miramos los permisos.
    Finalmente, si no tiene el rol adecuado, denegamos el acceso.

    Este patrón es muy habitual en programación web.


    33. Ejemplo práctico completo: carrito de compra

    Vamos a imaginar que tenemos una tienda online sencilla.

    Queremos comprobar si un producto se puede comprar.

    <?php

    $producto = "Monitor 24 pulgadas";
    $precio = 149.99;
    $stock = 3;
    $usuarioRegistrado = true;

    if ($stock <= 0) {
    echo "El producto $producto está agotado.";
    } elseif (!$usuarioRegistrado) {
    echo "Debes iniciar sesión para comprar.";
    } else {
    echo "Puedes comprar $producto por $precio euros.";
    }

    ?>

    Resultado:

    Puedes comprar Monitor 24 pulgadas por 149.99 euros.

    Ahora cambiamos el stock:

    <?php

    $producto = "Monitor 24 pulgadas";
    $precio = 149.99;
    $stock = 0;
    $usuarioRegistrado = true;

    if ($stock <= 0) {
    echo "El producto $producto está agotado.";
    } elseif (!$usuarioRegistrado) {
    echo "Debes iniciar sesión para comprar.";
    } else {
    echo "Puedes comprar $producto por $precio euros.";
    }

    ?>

    Resultado:

    El producto Monitor 24 pulgadas está agotado.

    Fíjate en que, si el producto está agotado, ya no tiene sentido comprobar si el usuario está registrado. PHP entra en el primer bloque y termina la estructura condicional.


    34. Ejemplo práctico completo: cálculo de descuento

    Vamos a crear un pequeño sistema de descuentos.

    Si el cliente compra más de 100 euros, tiene un 10% de descuento.
    Si compra más de 200 euros, tiene un 20% de descuento.
    Si compra 100 euros o menos, no tiene descuento.

    <?php

    $totalCompra = 250;

    if ($totalCompra > 200) {
    $descuento = 20;
    } elseif ($totalCompra > 100) {
    $descuento = 10;
    } else {
    $descuento = 0;
    }

    $importeDescuento = $totalCompra * $descuento / 100;
    $totalFinal = $totalCompra - $importeDescuento;

    echo "Total inicial: $totalCompra euros<br>";
    echo "Descuento aplicado: $descuento%<br>";
    echo "Importe descontado: $importeDescuento euros<br>";
    echo "Total final: $totalFinal euros";

    ?>

    Resultado aproximado:

    Total inicial: 250 euros
    Descuento aplicado: 20%
    Importe descontado: 50 euros
    Total final: 200 euros

    El orden aquí también importa. Primero comprobamos la condición más alta:

    $totalCompra > 200

    Si empezáramos por $totalCompra > 100, una compra de 250 euros entraría ahí y solo recibiría un 10% de descuento.


    35. Ejemplo práctico completo: reserva de habitación

    Imaginemos una aplicación muy sencilla para reservar una habitación.

    Queremos comprobar:

    Que hay habitaciones disponibles.
    Que el cliente ha indicado número de noches.
    Que el número de noches es válido.
    Que el cliente acepta las condiciones.

    <?php

    $habitacionesDisponibles = 4;
    $noches = 3;
    $aceptaCondiciones = true;
    $precioPorNoche = 60;

    if ($habitacionesDisponibles <= 0) {
    echo "No hay habitaciones disponibles.";
    } elseif ($noches <= 0) {
    echo "Debes indicar un número de noches válido.";
    } elseif (!$aceptaCondiciones) {
    echo "Debes aceptar las condiciones de la reserva.";
    } else {
    $precioTotal = $noches * $precioPorNoche;

    echo "Reserva realizada correctamente.<br>";
    echo "Noches reservadas: $noches<br>";
    echo "Precio total: $precioTotal euros";
    }

    ?>

    Este ejemplo es interesante porque dentro del else no solo mostramos un mensaje, sino que hacemos un cálculo.

    Esto es habitual: primero validamos, después procesamos.


    36. Ejemplo práctico completo: panel según rol de usuario

    Una web puede mostrar opciones diferentes dependiendo del tipo de usuario.

    <?php

    $rol = "admin";

    if ($rol === "admin") {
    echo "<h2>Panel de administración</h2>";
    echo "<p>Puedes gestionar usuarios, productos y reservas.</p>";
    } elseif ($rol === "editor") {
    echo "<h2>Panel de edición</h2>";
    echo "<p>Puedes crear y modificar contenidos.</p>";
    } elseif ($rol === "cliente") {
    echo "<h2>Zona de cliente</h2>";
    echo "<p>Puedes consultar tus pedidos y modificar tus datos.</p>";
    } else {
    echo "<h2>Acceso limitado</h2>";
    echo "<p>No se reconoce tu rol de usuario.</p>";
    }

    ?>

    Aquí PHP no solo toma una decisión lógica, también genera HTML diferente según el caso.

    Este es uno de los motivos por los que PHP se usa tanto en desarrollo web: puede mezclar lógica del servidor con generación dinámica de contenido HTML.


    37. Alternar PHP y HTML en condicionales

    También podemos escribir condicionales mezclando PHP y HTML de otra forma.

    Ejemplo:

    <?php
    $usuarioRegistrado = true;
    ?>

    <!DOCTYPE html>
    <html lang="es">
    <head>
    <meta charset="UTF-8">
    <title>Zona privada</title>
    </head>
    <body>

    <?php if ($usuarioRegistrado): ?>
    <h1>Bienvenido a tu cuenta</h1>
    <p>Desde aquí puedes gestionar tus datos.</p>
    <?php else: ?>
    <h1>Acceso no permitido</h1>
    <p>Debes iniciar sesión para ver esta página.</p>
    <?php endif; ?>

    </body>
    </html>

    Esta sintaxis alternativa es bastante usada en plantillas PHP, porque puede resultar más legible cuando hay mucho HTML.

    En lugar de abrir y cerrar llaves {}, usamos:

    <?php if (condicion): ?>
    HTML
    <?php else: ?>
    HTML
    <?php endif; ?>

    No es obligatorio usarla, pero conviene conocerla porque aparece en muchos proyectos PHP y en plantillas de WordPress.


    38. Otro ejemplo con HTML: mostrar un aviso de stock

    <?php
    $producto = "Teclado mecánico";
    $stock = 0;
    ?>

    <!DOCTYPE html>
    <html lang="es">
    <head>
    <meta charset="UTF-8">
    <title>Producto</title>
    </head>
    <body>

    <h1><?php echo $producto; ?></h1>

    <?php if ($stock > 0): ?>
    <p>Producto disponible.</p>
    <button>Comprar</button>
    <?php else: ?>
    <p>Producto agotado.</p>
    <button disabled>No disponible</button>
    <?php endif; ?>

    </body>
    </html>

    Este ejemplo representa una situación muy real. En una tienda online no queremos mostrar el mismo botón si el producto está disponible que si está agotado.


    39. Condicionales y seguridad básica

    Los condicionales también ayudan a proteger partes de una aplicación.

    Por ejemplo, podemos impedir que un usuario no identificado vea una página privada.

    <?php

    $logueado = false;

    if (!$logueado) {
    echo "No tienes permiso para acceder a esta página.";
    exit;
    }

    echo "Contenido privado de la aplicación.";

    ?>

    La función exit detiene la ejecución del script.

    Esto significa que si el usuario no está logueado, PHP muestra el mensaje y deja de ejecutar el resto del archivo.

    Más adelante, cuando trabajemos con sesiones, este tipo de código será muy habitual:

    <?php

    session_start();

    if (!isset($_SESSION["usuario"])) {
    echo "Debes iniciar sesión.";
    exit;
    }

    echo "Bienvenido a la zona privada.";

    ?>

    En este ejemplo todavía aparecen elementos que se estudiarán más adelante, como session_start() y $_SESSION, pero la idea principal ya se entiende: usamos un condicional para proteger una parte del programa.


    40. isset() y empty()

    PHP tiene funciones muy utilizadas para comprobar variables.

    La función isset() comprueba si una variable existe y no es null.

    Ejemplo:

    <?php

    if (isset($_POST["nombre"])) {
    echo "El campo nombre ha sido enviado.";
    } else {
    echo "El campo nombre no existe.";
    }

    ?>

    La función empty() comprueba si una variable está vacía.

    Ejemplo:

    <?php

    $nombre = "";

    if (empty($nombre)) {
    echo "El nombre está vacío.";
    } else {
    echo "El nombre tiene contenido.";
    }

    ?>

    Hay que tener cuidado con empty(), porque considera vacíos varios valores, como "", 0, "0", null, false o [].

    Ejemplo:

    <?php

    $stock = 0;

    if (empty($stock)) {
    echo "No hay stock o el valor está vacío.";
    }

    ?>

    Aunque $stock existe y vale 0, empty() lo considera vacío.

    Por eso, en algunos casos es mejor hacer comprobaciones explícitas:

    <?php

    $stock = 0;

    if ($stock === 0) {
    echo "El producto está agotado.";
    }

    ?>

    La idea importante es esta: no basta con saber que una función existe; hay que saber exactamente qué está comprobando.


    41. Ejemplo práctico: validar un formulario de login

    Formulario login.html:

    <form action="login.php" method="post">
    <label for="usuario">Usuario:</label>
    <input type="text" name="usuario" id="usuario">

    <br><br>

    <label for="password">Contraseña:</label>
    <input type="password" name="password" id="password">

    <br><br>

    <button type="submit">Entrar</button>
    </form>

    Archivo login.php:

    <?php

    $usuario = $_POST["usuario"] ?? "";
    $password = $_POST["password"] ?? "";

    if ($usuario === "" || $password === "") {
    echo "Debes introducir usuario y contraseña.";
    } elseif ($usuario === "admin" && $password === "1234") {
    echo "Acceso correcto.";
    } else {
    echo "Usuario o contraseña incorrectos.";
    }

    ?>

    Este ejemplo todavía no usa base de datos, pero la lógica principal ya está ahí:

    Primero comprobamos si faltan datos.
    Después comprobamos si los datos son correctos.
    Si no son correctos, mostramos un error.

    Más adelante cambiaremos la comparación directa por una consulta a la base de datos.


    42. Ejemplo práctico: validar un registro de usuario

    Vamos a crear una validación algo más extensa.

    <?php

    $nombre = $_POST["nombre"] ?? "";
    $email = $_POST["email"] ?? "";
    $password = $_POST["password"] ?? "";
    $repetirPassword = $_POST["repetir_password"] ?? "";
    $aceptaCondiciones = isset($_POST["condiciones"]);

    if ($nombre === "") {
    echo "El nombre es obligatorio.";
    } elseif ($email === "") {
    echo "El email es obligatorio.";
    } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    echo "El email no tiene un formato válido.";
    } elseif ($password === "") {
    echo "La contraseña es obligatoria.";
    } elseif (strlen($password) < 6) {
    echo "La contraseña debe tener al menos 6 caracteres.";
    } elseif ($password !== $repetirPassword) {
    echo "Las contraseñas no coinciden.";
    } elseif (!$aceptaCondiciones) {
    echo "Debes aceptar las condiciones.";
    } else {
    echo "Registro completado correctamente.";
    }

    ?>

    Aquí aparecen dos funciones útiles:

    filter_var($email, FILTER_VALIDATE_EMAIL)

    Sirve para comprobar si un email tiene un formato válido.

    strlen($password)

    Devuelve la longitud de una cadena de texto.

    Este ejemplo es muy representativo de cómo se trabaja en aplicaciones web: recogemos datos, comprobamos condiciones y, si todo es correcto, continuamos.


    43. Ejemplo práctico: mostrar errores acumulados

    En el ejemplo anterior solo mostramos el primer error encontrado. Eso está bien para empezar, pero en una aplicación real puede interesarnos mostrar todos los errores a la vez.

    Para eso podemos usar un array de errores.

    <?php

    $nombre = $_POST["nombre"] ?? "";
    $email = $_POST["email"] ?? "";
    $password = $_POST["password"] ?? "";

    $errores = [];

    if ($nombre === "") {
    $errores[] = "El nombre es obligatorio.";
    }

    if ($email === "") {
    $errores[] = "El email es obligatorio.";
    } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    $errores[] = "El email no tiene un formato válido.";
    }

    if ($password === "") {
    $errores[] = "La contraseña es obligatoria.";
    } elseif (strlen($password) < 6) {
    $errores[] = "La contraseña debe tener al menos 6 caracteres.";
    }

    if (count($errores) > 0) {
    echo "<h2>Se han encontrado errores:</h2>";

    foreach ($errores as $error) {
    echo "<p>$error</p>";
    }
    } else {
    echo "Registro correcto.";
    }

    ?>

    Este ejemplo es más avanzado, pero merece la pena verlo porque representa una forma más realista de validar formularios.

    En lugar de parar en el primer error, vamos guardando todos los problemas encontrados en el array $errores.

    Al final, comprobamos cuántos errores hay:

    count($errores) > 0

    Si hay errores, los mostramos.
    Si no hay errores, continuamos.


    44. Ejemplo práctico: semáforo

    Vamos a practicar con un ejemplo muy visual.

    <?php

    $color = "rojo";

    if ($color === "verde") {
    echo "Puedes pasar.";
    } elseif ($color === "amarillo") {
    echo "Precaución, prepárate para detenerte.";
    } elseif ($color === "rojo") {
    echo "Debes detenerte.";
    } else {
    echo "Color no reconocido.";
    }

    ?>

    También podríamos hacerlo con match:

    <?php

    $color = "rojo";

    $mensaje = match ($color) {
    "verde" => "Puedes pasar.",
    "amarillo" => "Precaución, prepárate para detenerte.",
    "rojo" => "Debes detenerte.",
    default => "Color no reconocido.",
    };

    echo $mensaje;

    ?>

    Este ejemplo es sencillo, pero ayuda a entender cómo una variable puede dirigir el comportamiento del programa.


    45. Ejemplo práctico: cajero automático

    Vamos a simular una operación de retirada de dinero.

    <?php

    $saldo = 500;
    $cantidadRetirar = 700;

    if ($cantidadRetirar <= 0) {
    echo "La cantidad debe ser mayor que cero.";
    } elseif ($cantidadRetirar > $saldo) {
    echo "No tienes saldo suficiente.";
    } else {
    $saldo = $saldo - $cantidadRetirar;

    echo "Operación realizada correctamente.<br>";
    echo "Nuevo saldo: $saldo euros.";
    }

    ?>

    En este ejemplo hay una validación clara:

    No se puede retirar una cantidad negativa o cero.
    No se puede retirar más dinero del saldo disponible.
    Si todo es correcto, se realiza la operación.

    Este patrón de validación aparece constantemente en programación.


    46. Ejemplo práctico: cálculo de envío

    Vamos a simular una tienda online.

    Queremos que el envío sea gratis si la compra supera los 50 euros.

    <?php

    $totalCompra = 42;
    $costeEnvio = 4.99;

    if ($totalCompra >= 50) {
    $costeEnvio = 0;
    }

    $totalFinal = $totalCompra + $costeEnvio;

    echo "Compra: $totalCompra euros<br>";
    echo "Envío: $costeEnvio euros<br>";
    echo "Total: $totalFinal euros";

    ?>

    Si $totalCompra vale 42, el envío se mantiene en 4.99.

    Si cambiamos la compra:

    <?php

    $totalCompra = 75;
    $costeEnvio = 4.99;

    if ($totalCompra >= 50) {
    $costeEnvio = 0;
    }

    $totalFinal = $totalCompra + $costeEnvio;

    echo "Compra: $totalCompra euros<br>";
    echo "Envío: $costeEnvio euros<br>";
    echo "Total: $totalFinal euros";

    ?>

    Ahora el envío será gratuito.


    47. Ejemplo práctico: control de temperatura

    <?php

    $temperatura = 31;

    if ($temperatura < 0) {
    echo "Hace mucho frío.";
    } elseif ($temperatura <= 15) {
    echo "Hace frío.";
    } elseif ($temperatura <= 25) {
    echo "Temperatura agradable.";
    } elseif ($temperatura <= 35) {
    echo "Hace calor.";
    } else {
    echo "Hace mucho calor.";
    }

    ?>

    Este ejemplo sirve para practicar rangos.

    Cuando trabajamos con rangos, hay que prestar mucha atención a los límites.

    Por ejemplo:

    $temperatura <= 15

    incluye el valor 15.

    Mientras que:

    $temperatura < 15

    no lo incluiría.


    48. Ejemplo práctico: recomendador sencillo

    Podemos usar condicionales para crear un recomendador muy simple.

    <?php

    $presupuesto = 800;
    $uso = "programacion";

    if ($presupuesto < 500) {
    echo "Te recomendamos un equipo básico para tareas de oficina y navegación.";
    } elseif ($presupuesto <= 1000 && $uso === "programacion") {
    echo "Te recomendamos un portátil con buen procesador y al menos 16 GB de RAM.";
    } elseif ($presupuesto <= 1000 && $uso === "videojuegos") {
    echo "Te recomendamos buscar un equipo con tarjeta gráfica dedicada.";
    } elseif ($presupuesto > 1000 && $uso === "programacion") {
    echo "Puedes optar por un equipo potente para desarrollo, máquinas virtuales y Docker.";
    } else {
    echo "Necesitamos más información para hacer una recomendación.";
    }

    ?>

    Este ejemplo combina comparación numérica y comparación de cadenas.


    49. Errores comunes al trabajar con condicionales

    Uno de los errores más habituales es usar = en vez de == o ===.

    Esto está mal:

    <?php

    $usuario = "cliente";

    if ($usuario = "admin") {
    echo "Eres administrador.";
    }

    ?>

    El operador = no compara. El operador = asigna.

    Es decir, en vez de comprobar si $usuario es "admin", estamos cambiando el valor de $usuario.

    La comparación correcta sería:

    <?php

    $usuario = "cliente";

    if ($usuario === "admin") {
    echo "Eres administrador.";
    } else {
    echo "No eres administrador.";
    }

    ?>

    Otro error habitual es olvidar las llaves:

    <?php

    $edad = 20;

    if ($edad >= 18)
    echo "Eres mayor de edad.";
    echo "Puedes acceder.";

    ?>

    Aunque visualmente pueda parecer que las dos líneas dependen del if, realmente solo la primera instrucción depende de la condición.

    Por eso es mejor usar siempre llaves:

    <?php

    $edad = 20;

    if ($edad >= 18) {
    echo "Eres mayor de edad.";
    echo "Puedes acceder.";
    }

    ?>

    Esto evita errores y mejora la lectura.


    50. Buenas prácticas con condicionales

    Aunque los condicionales son sencillos de entender, conviene usarlos con orden.

    Es recomendable escribir condiciones claras y fáciles de leer. Si una condición se vuelve demasiado larga, podemos guardarla en una variable.

    Por ejemplo:

    <?php

    $edad = 22;
    $tieneEntrada = true;
    $estaVetado = false;

    $puedeEntrar = $edad >= 18 && $tieneEntrada && !$estaVetado;

    if ($puedeEntrar) {
    echo "Puedes entrar.";
    } else {
    echo "No puedes entrar.";
    }

    ?>

    La variable $puedeEntrar hace que el if sea mucho más legible.

    También conviene validar primero los casos de error. Esto evita estructuras demasiado anidadas.

    En lugar de escribir un código muy profundo, como este:

    <?php

    if ($usuario !== "") {
    if ($password !== "") {
    if (strlen($password) >= 6) {
    echo "Datos correctos.";
    } else {
    echo "La contraseña es demasiado corta.";
    }
    } else {
    echo "La contraseña es obligatoria.";
    }
    } else {
    echo "El usuario es obligatorio.";
    }

    ?>

    Podemos escribirlo así:

    <?php

    if ($usuario === "") {
    echo "El usuario es obligatorio.";
    } elseif ($password === "") {
    echo "La contraseña es obligatoria.";
    } elseif (strlen($password) < 6) {
    echo "La contraseña es demasiado corta.";
    } else {
    echo "Datos correctos.";
    }

    ?>

    Este segundo código es más limpio y más fácil de mantener.


    Práctica guiada: sistema de acceso a una plataforma

    Vamos a crear una pequeña práctica usando condicionales.

    Queremos simular el acceso a una plataforma de alumnos.

    Cada alumno tendrá:

    • Nombre.
    • Edad.
    • Usuario.
    • Contraseña.
    • Estado de matrícula.
    • Rol.

    El programa deberá comprobar si puede acceder.

    <?php

    $nombre = "Laura";
    $edad = 19;
    $usuario = "laura";
    $password = "abc123";
    $matriculaActiva = true;
    $rol = "alumno";

    if ($usuario === "" || $password === "") {
    echo "Debes introducir usuario y contraseña.";
    } elseif ($usuario !== "laura" || $password !== "abc123") {
    echo "Usuario o contraseña incorrectos.";
    } elseif ($edad < 18) {
    echo "Debes ser mayor de edad para acceder a esta plataforma.";
    } elseif (!$matriculaActiva) {
    echo "Tu matrícula no está activa.";
    } elseif ($rol === "alumno") {
    echo "Bienvenida, $nombre. Has accedido como alumna.";
    } elseif ($rol === "profesor") {
    echo "Bienvenida, $nombre. Has accedido como profesora.";
    } elseif ($rol === "admin") {
    echo "Bienvenida, $nombre. Has accedido como administradora.";
    } else {
    echo "Rol no reconocido.";
    }

    ?>

    Este ejercicio resume muchas de las ideas del tema:

    • Comprobación de campos vacíos.
    • Comparación de usuario y contraseña.
    • Validación de edad.
    • Uso de variables booleanas.
    • Comprobación de roles.
    • Uso ordenado de if, elseif y else.

    Práctica guiada: calculadora de precio de reserva

    Vamos a crear otro ejemplo completo relacionado con reservas.

    El sistema debe calcular el precio final de una reserva teniendo en cuenta:

    • Número de noches.
    • Precio por noche.
    • Temporada.
    • Descuento si reserva más de 7 noches.
    • Validaciones básicas.
    <?php

    $noches = 8;
    $precioPorNoche = 70;
    $temporada = "alta";

    if ($noches <= 0) {
    echo "El número de noches no es válido.";
    } elseif ($precioPorNoche <= 0) {
    echo "El precio por noche no es válido.";
    } else {
    $precioBase = $noches * $precioPorNoche;

    if ($temporada === "alta") {
    $suplemento = $precioBase * 0.20;
    } elseif ($temporada === "media") {
    $suplemento = $precioBase * 0.10;
    } elseif ($temporada === "baja") {
    $suplemento = 0;
    } else {
    $suplemento = 0;
    echo "Temporada no reconocida. Se aplicará precio base.<br>";
    }

    if ($noches > 7) {
    $descuento = $precioBase * 0.15;
    } else {
    $descuento = 0;
    }

    $precioFinal = $precioBase + $suplemento - $descuento;

    echo "Noches: $noches<br>";
    echo "Precio por noche: $precioPorNoche euros<br>";
    echo "Precio base: $precioBase euros<br>";
    echo "Suplemento: $suplemento euros<br>";
    echo "Descuento: $descuento euros<br>";
    echo "Precio final: $precioFinal euros";
    }

    ?>

    Este ejemplo es bastante completo porque combina validación, cálculos y decisiones.


    Ejercicios propuestos

    Ejercicio 1: mayoría de edad

    Crea un script PHP que guarde una edad en una variable y muestre si la persona es menor o mayor de edad.

    Después modifica el programa para que también indique si la edad no es válida cuando sea menor que 0.


    Ejercicio 2: nota de un alumno

    Crea un programa que reciba una nota y muestre:

    Suspenso si es menor que 5.
    Aprobado si está entre 5 y 6.99.
    Notable si está entre 7 y 8.99.
    Sobresaliente si está entre 9 y 10.
    Nota no válida si está fuera del rango de 0 a 10.


    Ejercicio 3: login sencillo

    Crea dos variables:

    $usuario = "admin";
    $password = "1234";

    Después crea un condicional que compruebe si el usuario y la contraseña son correctos.

    Si son correctos, debe mostrar:

    Acceso permitido

    Si no, debe mostrar:

    Acceso denegado

    Ejercicio 4: tienda online

    Crea un programa con estas variables:

    $producto = "Ratón inalámbrico";
    $precio = 25;
    $stock = 10;
    $usuarioRegistrado = true;

    El programa debe comprobar si el producto tiene stock y si el usuario está registrado.

    Si todo es correcto, debe mostrar que el producto se puede comprar.

    Si no hay stock, debe indicar que el producto está agotado.

    Si el usuario no está registrado, debe indicar que debe iniciar sesión.


    Ejercicio 5: roles de usuario

    Crea una variable $rol con uno de estos valores:

    "admin"
    "editor"
    "cliente"
    "invitado"

    Usa condicionales para mostrar un mensaje diferente según el rol.

    Después repite el ejercicio usando switch.


    Ejercicio 6: formulario de contacto

    Crea un formulario HTML con los campos:

    Nombre.
    Email.
    Mensaje.

    Después crea un archivo PHP que valide:

    Que el nombre no esté vacío.
    Que el email no esté vacío.
    Que el email tenga formato válido.
    Que el mensaje tenga al menos 10 caracteres.

    Si todo es correcto, debe mostrar:

    Formulario enviado correctamente

    Resumen del tema

    • Los condicionales permiten que un programa tome decisiones.
    • La estructura más básica es if.
    • Cuando queremos ejecutar una alternativa usamos else.
    • Cuando tenemos varias posibilidades usamos elseif.
    • Para comparar una variable con muchos valores posibles podemos usar switch o match.
    • Los operadores de comparación permiten comprobar igualdad, diferencia, mayor que, menor que, etc.
    • Los operadores lógicos permiten combinar condiciones usando &&, || y !.
    • En PHP es importante diferenciar entre == y ===.
    • Los condicionales son fundamentales para validar formularios, controlar accesos, calcular descuentos, mostrar contenido según el usuario y proteger zonas privadas.
    • A partir de este punto, PHP deja de ser una simple secuencia de instrucciones y empieza a comportarse como un programa capaz de reaccionar ante distintas situaciones.
  • 1.8 – Bucles en PHP: repetir instrucciones de forma controlada

    1.8 – Bucles en PHP: repetir instrucciones de forma controlada

    En programación hay muchas situaciones en las que necesitamos repetir una misma acción varias veces. Por ejemplo, mostrar los números del 1 al 10, recorrer una lista de productos, leer los datos de varios alumnos, calcular el total de un carrito o mostrar las filas de una tabla HTML.

    Podríamos escribir el mismo código muchas veces, pero sería una mala solución. El código sería largo, difícil de mantener y muy propenso a errores. Para solucionar esto existen los bucles, también llamados estructuras repetitivas.

    Un bucle permite ejecutar un bloque de código mientras se cumpla una condición o durante un número determinado de repeticiones.

    En PHP trabajaremos principalmente con estas estructuras:

    • while
    • do while
    • for
    • foreach

    Además, veremos instrucciones como break y continue, que nos permiten modificar el comportamiento normal de un bucle.


    1. ¿Qué es un bucle?

    Un bucle es una estructura que repite un bloque de instrucciones.

    Imagina que queremos mostrar los números del 1 al 5.

    Podríamos hacerlo así:

    <?php
    echo 1;
    echo 2;
    echo 3;
    echo 4;
    echo 5;
    ?>

    Funciona, pero no es práctico. Si tuviéramos que mostrar los números del 1 al 100, tendríamos que escribir cien líneas. Y si mañana queremos mostrar hasta el 1000, el problema sería todavía peor.

    Con un bucle podemos hacerlo de forma mucho más limpia:

    <?php
    $numero = 1;

    while ($numero <= 5) {
    echo $numero . "<br>";
    $numero++;
    }
    ?>

    Este código dice:

    Mientras $numero sea menor o igual que 5, muestra el número y luego súmale 1.

    El resultado será:

    1
    2
    3
    4
    5

    La clave de los bucles es entender que el programa no avanza simplemente de arriba hacia abajo una sola vez, sino que vuelve hacia atrás para repetir una parte del código.


    2. Partes importantes de un bucle

    Aunque cada tipo de bucle se escribe de forma diferente, casi todos tienen tres elementos importantes:

    Primero, una variable de control, que normalmente sirve para contar o recorrer datos.

    Segundo, una condición, que decide si el bucle debe seguir ejecutándose.

    Tercero, una actualización, que modifica la variable de control para que el bucle pueda avanzar y terminar en algún momento.

    Veamos este ejemplo:

    <?php
    $contador = 1;

    while ($contador <= 10) {
    echo "Vuelta número: " . $contador . "<br>";
    $contador++;
    }
    ?>

    Aquí:

    $contador = 1 es el valor inicial.

    $contador <= 10 es la condición.

    $contador++ aumenta el contador en cada vuelta.

    Si olvidamos actualizar la variable, podemos crear un bucle infinito.

    Por ejemplo:

    <?php
    $contador = 1;

    while ($contador <= 10) {
    echo "Esto no terminará nunca<br>";
    }
    ?>

    Este bucle nunca terminaría porque $contador siempre vale 1. La condición $contador <= 10 siempre será verdadera.

    Este es uno de los errores más habituales cuando se empieza a trabajar con bucles.


    3. El bucle while

    El bucle while significa literalmente mientras.

    Su estructura básica es:

    while (condición) {
    // Código que se repite
    }

    El código dentro del bucle se ejecutará mientras la condición sea verdadera.

    Ejemplo básico:

    <?php
    $numero = 1;

    while ($numero <= 5) {
    echo "Número: " . $numero . "<br>";
    $numero++;
    }
    ?>

    El bucle empieza comprobando la condición. Si la condición es verdadera, entra dentro del bloque. Cuando termina el bloque, vuelve a comprobar la condición. Si sigue siendo verdadera, repite. Cuando la condición deja de cumplirse, el bucle termina.


    Ejemplo práctico: mostrar una cuenta atrás

    <?php
    $cuenta = 10;

    while ($cuenta >= 1) {
    echo $cuenta . "<br>";
    $cuenta--;
    }

    echo "¡Despegue!";
    ?>

    Resultado:

    10
    9
    8
    7
    6
    5
    4
    3
    2
    1
    ¡Despegue!

    En este caso no estamos sumando, sino restando. La variable empieza en 10 y va bajando hasta llegar a 1.


    Ejemplo práctico: sumar números del 1 al 100

    Supongamos que queremos calcular la suma de todos los números del 1 al 100.

    <?php
    $numero = 1;
    $suma = 0;

    while ($numero <= 100) {
    $suma = $suma + $numero;
    $numero++;
    }

    echo "La suma total es: " . $suma;
    ?>

    Aquí aparecen dos variables importantes.

    $numero controla el bucle.

    $suma acumula el resultado.

    La variable $suma empieza en 0. En cada vuelta se le añade el valor actual de $numero.

    Primero suma 1, luego 2, luego 3, y así sucesivamente hasta 100.


    Ejemplo práctico: validar una contraseña simulada

    Imaginemos que queremos comprobar varios intentos de contraseña. Más adelante esto se podría relacionar con formularios, sesiones o bases de datos.

    <?php
    $passwordCorrecta = "admin123";
    $intento = "admin123";
    $intentos = 1;

    while ($intento != $passwordCorrecta && $intentos < 3) {
    echo "Contraseña incorrecta<br>";
    $intentos++;
    }

    if ($intento == $passwordCorrecta) {
    echo "Acceso permitido";
    } else {
    echo "Acceso bloqueado";
    }
    ?>

    Este ejemplo todavía está simplificado porque el intento está escrito directamente en el código. Más adelante podríamos recibir el valor desde un formulario usando $_POST.

    Lo importante aquí es ver que el bucle puede depender de más de una condición.

    La condición es:

    $intento != $passwordCorrecta && $intentos < 3

    Esto significa:

    Mientras la contraseña sea incorrecta y queden intentos disponibles, el bucle podría repetirse.


    4. El bucle do while

    El bucle do while se parece mucho al while, pero tiene una diferencia muy importante.

    En un while, primero se comprueba la condición y después se ejecuta el código.

    En un do while, primero se ejecuta el código y después se comprueba la condición.

    Su estructura es:

    do {
    // Código que se repite
    } while (condición);

    Observa que al final lleva punto y coma.

    Ejemplo:

    <?php
    $numero = 1;

    do {
    echo "Número: " . $numero . "<br>";
    $numero++;
    } while ($numero <= 5);
    ?>

    El resultado será el mismo que antes:

    Número: 1
    Número: 2
    Número: 3
    Número: 4
    Número: 5

    La diferencia aparece cuando la condición inicialmente es falsa.


    Diferencia entre while y do while

    Ejemplo con while:

    <?php
    $numero = 10;

    while ($numero <= 5) {
    echo "Este mensaje no se muestra";
    }
    ?>

    Este código no muestra nada, porque la condición se comprueba antes de entrar.

    Ahora el mismo caso con do while:

    <?php
    $numero = 10;

    do {
    echo "Este mensaje se muestra una vez";
    } while ($numero <= 5);
    ?>

    Aunque la condición es falsa, el bloque se ejecuta una vez antes de comprobarla.

    Esto hace que do while sea útil cuando queremos que algo ocurra al menos una vez.


    Ejemplo práctico: menú de opciones

    Un caso típico de do while es un menú. Queremos mostrar el menú al menos una vez, y luego repetirlo si el usuario no elige salir.

    En un programa de consola tendría mucho sentido. En PHP web no se usa exactamente igual porque las páginas web funcionan por peticiones, pero como ejercicio de lógica es muy útil.

    <?php
    $opcion = 1;

    do {
    echo "Menú principal<br>";
    echo "1. Ver productos<br>";
    echo "2. Ver carrito<br>";
    echo "3. Salir<br><br>";

    echo "Has elegido la opción: " . $opcion . "<br>";

    $opcion++;

    } while ($opcion <= 3);
    ?>

    Este ejemplo simula que la opción va cambiando. Más adelante, cuando se trabaje con formularios o aplicaciones de consola, el valor podría venir del usuario.


    5. El bucle for

    El bucle for se utiliza mucho cuando sabemos cuántas veces queremos repetir algo.

    Su estructura es:

    for (inicio; condición; actualización) {
    // Código que se repite
    }

    Ejemplo:

    <?php
    for ($i = 1; $i <= 5; $i++) {
    echo "Número: " . $i . "<br>";
    }
    ?>

    Este bucle tiene todo en una sola línea:

    $i = 1 indica el valor inicial.

    $i <= 5 es la condición.

    $i++ indica que al final de cada vuelta se suma 1.

    El resultado será:

    Número: 1
    Número: 2
    Número: 3
    Número: 4
    Número: 5

    Comparación entre while y for

    Este código con while:

    <?php
    $i = 1;

    while ($i <= 5) {
    echo $i . "<br>";
    $i++;
    }
    ?>

    Se puede escribir con for así:

    <?php
    for ($i = 1; $i <= 5; $i++) {
    echo $i . "<br>";
    }
    ?>

    Los dos hacen lo mismo. La diferencia es que el for agrupa en una sola línea el inicio, la condición y la actualización.

    Cuando estamos contando repeticiones, normalmente for resulta más cómodo.


    Ejemplo práctico: tabla de multiplicar

    <?php
    $numero = 7;

    echo "<h2>Tabla del " . $numero . "</h2>";

    for ($i = 1; $i <= 10; $i++) {
    $resultado = $numero * $i;
    echo $numero . " x " . $i . " = " . $resultado . "<br>";
    }
    ?>

    Resultado:

    7 x 1 = 7
    7 x 2 = 14
    7 x 3 = 21
    ...
    7 x 10 = 70

    Este ejemplo es muy importante porque muestra una situación real donde el bucle evita repetir código.

    Sin bucle, tendríamos que escribir diez líneas casi iguales. Con el bucle, cambiamos únicamente el valor de $i.


    Ejemplo práctico: crear una lista HTML

    PHP se utiliza muchas veces para generar HTML dinámicamente.

    Por ejemplo, podemos crear una lista de números:

    <?php
    echo "<ul>";

    for ($i = 1; $i <= 5; $i++) {
    echo "<li>Elemento " . $i . "</li>";
    }

    echo "</ul>";
    ?>

    El navegador recibiría algo parecido a esto:

    <ul>
    <li>Elemento 1</li>
    <li>Elemento 2</li>
    <li>Elemento 3</li>
    <li>Elemento 4</li>
    <li>Elemento 5</li>
    </ul>

    Este es uno de los usos más importantes de PHP: generar contenido HTML a partir de datos.


    Ejemplo práctico: generar una tabla HTML

    Vamos a crear una tabla con números del 1 al 10 y sus cuadrados.

    <?php
    echo "<table border='1'>";
    echo "<tr>";
    echo "<th>Número</th>";
    echo "<th>Cuadrado</th>";
    echo "</tr>";

    for ($i = 1; $i <= 10; $i++) {
    echo "<tr>";
    echo "<td>" . $i . "</td>";
    echo "<td>" . ($i * $i) . "</td>";
    echo "</tr>";
    }

    echo "</table>";
    ?>

    Este ejemplo mezcla programación con HTML. PHP se encarga de repetir las filas de la tabla.

    El resultado sería una tabla parecida a esta:

    NúmeroCuadrado
    11
    24
    39
    416
    525
    636
    749
    864
    981
    10100

    Este tipo de estructura será muy frecuente cuando más adelante mostremos productos, usuarios, reservas, pedidos o registros de una base de datos.


    6. Incrementos y decrementos

    En los bucles es habitual modificar una variable sumando o restando.

    PHP permite varias formas de hacerlo.

    $i = $i + 1;

    También podemos escribir:

    $i += 1;

    Y cuando solo queremos sumar uno:

    $i++;

    Las tres formas aumentan el valor de $i.

    Para restar uno:

    $i = $i - 1;
    $i -= 1;
    $i--;

    Ejemplo de bucle descendente:

    <?php
    for ($i = 10; $i >= 1; $i--) {
    echo $i . "<br>";
    }
    ?>

    Resultado:

    10
    9
    8
    7
    6
    5
    4
    3
    2
    1

    7. Bucles con saltos diferentes

    No siempre tenemos que avanzar de uno en uno. Podemos sumar de dos en dos, de cinco en cinco, o de la forma que necesitemos.

    Ejemplo: mostrar números pares del 2 al 20.

    <?php
    for ($i = 2; $i <= 20; $i += 2) {
    echo $i . "<br>";
    }
    ?>

    Resultado:

    2
    4
    6
    8
    10
    12
    14
    16
    18
    20

    También podríamos mostrar múltiplos de 5:

    <?php
    for ($i = 5; $i <= 50; $i += 5) {
    echo $i . "<br>";
    }
    ?>

    Resultado:

    5
    10
    15
    20
    25
    30
    35
    40
    45
    50

    8. Usar condicionales dentro de bucles

    Los bucles y los condicionales se combinan constantemente.

    Por ejemplo, podemos recorrer los números del 1 al 10 e indicar cuáles son pares y cuáles son impares.

    <?php
    for ($i = 1; $i <= 10; $i++) {
    if ($i % 2 == 0) {
    echo $i . " es par<br>";
    } else {
    echo $i . " es impar<br>";
    }
    }
    ?>

    El operador % calcula el resto de una división.

    Si un número dividido entre 2 tiene resto 0, es par.

    $i % 2 == 0

    Este tipo de combinación es fundamental. Un bucle permite recorrer datos. Un condicional permite tomar decisiones sobre cada dato.


    Ejemplo práctico: notas de alumnos

    Supongamos que tenemos varias notas y queremos mostrar si cada una está aprobada o suspensa.

    De momento usaremos un array sencillo. Aunque los arrays se estudien en profundidad más adelante, este ejemplo ayuda a entender muy bien la utilidad de los bucles.

    <?php
    $notas = [8, 4, 6, 3, 9, 5];

    for ($i = 0; $i < count($notas); $i++) {
    echo "Nota: " . $notas[$i] . " - ";

    if ($notas[$i] >= 5) {
    echo "Aprobado<br>";
    } else {
    echo "Suspenso<br>";
    }
    }
    ?>

    Resultado:

    Nota: 8 - Aprobado
    Nota: 4 - Suspenso
    Nota: 6 - Aprobado
    Nota: 3 - Suspenso
    Nota: 9 - Aprobado
    Nota: 5 - Aprobado

    Observa que los arrays en PHP empiezan en la posición 0.

    La primera nota está en:

    $notas[0]

    La segunda está en:

    $notas[1]

    Por eso el bucle empieza en 0:

    $i = 0

    Y termina antes de llegar al tamaño total del array:

    $i < count($notas)

    9. El bucle foreach

    El bucle foreach está especialmente pensado para recorrer arrays.

    Cuando tenemos una lista de elementos, foreach suele ser más cómodo que for.

    Su estructura básica es:

    foreach ($array as $elemento) {
    // Código que se repite por cada elemento
    }

    Ejemplo:

    <?php
    $frutas = ["Manzana", "Pera", "Naranja", "Plátano"];

    foreach ($frutas as $fruta) {
    echo $fruta . "<br>";
    }
    ?>

    Resultado:

    Manzana
    Pera
    Naranja
    Plátano

    En cada vuelta del bucle, PHP toma un elemento del array y lo guarda temporalmente en la variable $fruta.

    Primera vuelta: $fruta vale "Manzana".

    Segunda vuelta: $fruta vale "Pera".

    Tercera vuelta: $fruta vale "Naranja".

    Cuarta vuelta: $fruta vale "Plátano".

    Cuando se acaban los elementos, el bucle termina.


    Ejemplo práctico: lista de productos

    <?php
    $productos = ["Teclado", "Ratón", "Monitor", "Altavoces"];

    echo "<h2>Productos disponibles</h2>";
    echo "<ul>";

    foreach ($productos as $producto) {
    echo "<li>" . $producto . "</li>";
    }

    echo "</ul>";
    ?>

    Este ejemplo genera una lista HTML con los productos del array.

    En una aplicación real, esos productos podrían venir de una base de datos.


    foreach con clave y valor

    Los arrays pueden tener claves asociativas.

    Por ejemplo:

    <?php
    $usuario = [
    "nombre" => "Laura",
    "email" => "laura@email.com",
    "edad" => 24
    ];

    foreach ($usuario as $clave => $valor) {
    echo $clave . ": " . $valor . "<br>";
    }
    ?>

    Resultado:

    nombre: Laura
    email: laura@email.com
    edad: 24

    En este caso, en cada vuelta tenemos dos datos:

    $clave, que contiene el nombre del campo.

    $valor, que contiene el valor asociado.

    Esto es muy útil cuando queremos recorrer datos con estructura de ficha, como usuarios, productos, reservas o configuraciones.


    Ejemplo práctico: ficha de producto

    <?php
    $producto = [
    "nombre" => "Monitor 24 pulgadas",
    "precio" => 129.99,
    "stock" => 15,
    "categoria" => "Informática"
    ];

    echo "<h2>Ficha del producto</h2>";

    foreach ($producto as $campo => $valor) {
    echo "<strong>" . $campo . ":</strong> " . $valor . "<br>";
    }
    ?>

    Resultado:

    nombre: Monitor 24 pulgadas
    precio: 129.99
    stock: 15
    categoria: Informática

    Más adelante, cuando trabajemos con bases de datos, será muy frecuente recibir registros con una estructura parecida.


    10. Recorrer un array de arrays

    En aplicaciones reales, normalmente no tenemos un solo producto o un solo usuario. Tenemos muchos.

    Para representarlo podemos usar un array que contiene otros arrays.

    <?php
    $productos = [
    [
    "nombre" => "Teclado",
    "precio" => 25,
    "stock" => 10
    ],
    [
    "nombre" => "Ratón",
    "precio" => 15,
    "stock" => 20
    ],
    [
    "nombre" => "Monitor",
    "precio" => 150,
    "stock" => 5
    ]
    ];

    foreach ($productos as $producto) {
    echo "<h3>" . $producto["nombre"] . "</h3>";
    echo "Precio: " . $producto["precio"] . " €<br>";
    echo "Stock: " . $producto["stock"] . "<br>";
    echo "<hr>";
    }
    ?>

    Este ejemplo es muy parecido a lo que haríamos en una tienda online.

    Cada producto tiene varios datos. El foreach exterior recorre todos los productos. En cada vuelta, la variable $producto contiene un producto completo.

    Después accedemos a sus campos:

    $producto["nombre"]
    $producto["precio"]
    $producto["stock"]

    Ejemplo práctico: tabla de productos

    <?php
    $productos = [
    [
    "nombre" => "Teclado",
    "precio" => 25,
    "stock" => 10
    ],
    [
    "nombre" => "Ratón",
    "precio" => 15,
    "stock" => 20
    ],
    [
    "nombre" => "Monitor",
    "precio" => 150,
    "stock" => 5
    ]
    ];

    echo "<table border='1'>";
    echo "<tr>";
    echo "<th>Producto</th>";
    echo "<th>Precio</th>";
    echo "<th>Stock</th>";
    echo "</tr>";

    foreach ($productos as $producto) {
    echo "<tr>";
    echo "<td>" . $producto["nombre"] . "</td>";
    echo "<td>" . $producto["precio"] . " €</td>";
    echo "<td>" . $producto["stock"] . "</td>";
    echo "</tr>";
    }

    echo "</table>";
    ?>

    Este es uno de los ejemplos más importantes del tema.

    Aquí el bucle no solo repite texto. Está construyendo una tabla HTML completa a partir de datos.

    Esta lógica será esencial cuando más adelante hagamos consultas a MySQL y mostremos los resultados en una página web.


    11. Calcular totales con bucles

    Los bucles no solo sirven para mostrar información. También sirven para calcular.

    Vamos a calcular el total de un carrito de compra.

    <?php
    $carrito = [
    [
    "producto" => "Teclado",
    "precio" => 25,
    "cantidad" => 2
    ],
    [
    "producto" => "Ratón",
    "precio" => 15,
    "cantidad" => 1
    ],
    [
    "producto" => "Monitor",
    "precio" => 150,
    "cantidad" => 1
    ]
    ];

    $total = 0;

    foreach ($carrito as $linea) {
    $subtotal = $linea["precio"] * $linea["cantidad"];
    $total = $total + $subtotal;

    echo $linea["producto"] . ": " . $subtotal . " €<br>";
    }

    echo "<strong>Total del carrito: " . $total . " €</strong>";
    ?>

    Resultado:

    Teclado: 50 €
    Ratón: 15 €
    Monitor: 150 €
    Total del carrito: 215 €

    Aquí tenemos una variable acumuladora:

    $total = 0;

    En cada vuelta calculamos el subtotal de una línea:

    $subtotal = $linea["precio"] * $linea["cantidad"];

    Y luego lo añadimos al total:

    $total = $total + $subtotal;

    Esta técnica se utiliza muchísimo: sumar precios, contar aprobados, calcular estadísticas, acumular puntos, contar errores, calcular importes de reservas, etc.


    12. Contadores y acumuladores

    En los bucles aparecen dos conceptos muy importantes: contador y acumulador.

    Un contador normalmente suma de uno en uno. Sirve para contar cuántas veces ocurre algo.

    Un acumulador va guardando una suma total o un resultado progresivo.

    Ejemplo:

    <?php
    $notas = [8, 4, 6, 3, 9, 5];

    $aprobados = 0;
    $sumaNotas = 0;

    foreach ($notas as $nota) {
    $sumaNotas = $sumaNotas + $nota;

    if ($nota >= 5) {
    $aprobados++;
    }
    }

    $media = $sumaNotas / count($notas);

    echo "Aprobados: " . $aprobados . "<br>";
    echo "Media de la clase: " . $media;
    ?>

    En este ejemplo:

    $aprobados es un contador.

    $sumaNotas es un acumulador.

    La variable $aprobados solo aumenta cuando la nota es mayor o igual que 5.

    La variable $sumaNotas suma todas las notas.


    13. break: salir de un bucle

    La instrucción break permite terminar un bucle antes de que se cumpla su final normal.

    Ejemplo:

    <?php
    for ($i = 1; $i <= 10; $i++) {
    if ($i == 5) {
    break;
    }

    echo $i . "<br>";
    }
    ?>

    Resultado:

    1
    2
    3
    4

    Cuando $i vale 5, se ejecuta break y el bucle termina inmediatamente.


    Ejemplo práctico: buscar un producto

    <?php
    $productos = ["Teclado", "Ratón", "Monitor", "Altavoces"];
    $buscado = "Monitor";
    $encontrado = false;

    foreach ($productos as $producto) {
    if ($producto == $buscado) {
    $encontrado = true;
    break;
    }
    }

    if ($encontrado) {
    echo "Producto encontrado";
    } else {
    echo "Producto no encontrado";
    }
    ?>

    En este caso, cuando encontramos el producto, no necesitamos seguir recorriendo el resto del array. Por eso usamos break.

    Es una forma de hacer el programa más eficiente.


    14. continue: saltar una vuelta

    La instrucción continue no termina el bucle completo. Lo que hace es saltar la vuelta actual y pasar a la siguiente.

    Ejemplo:

    <?php
    for ($i = 1; $i <= 5; $i++) {
    if ($i == 3) {
    continue;
    }

    echo $i . "<br>";
    }
    ?>

    Resultado:

    1
    2
    4
    5

    Cuando $i vale 3, se ejecuta continue. El echo no se ejecuta en esa vuelta, pero el bucle continúa con el siguiente valor.


    Ejemplo práctico: mostrar solo productos con stock

    <?php
    $productos = [
    [
    "nombre" => "Teclado",
    "stock" => 10
    ],
    [
    "nombre" => "Ratón",
    "stock" => 0
    ],
    [
    "nombre" => "Monitor",
    "stock" => 5
    ]
    ];

    foreach ($productos as $producto) {
    if ($producto["stock"] == 0) {
    continue;
    }

    echo $producto["nombre"] . " disponible<br>";
    }
    ?>

    Resultado:

    Teclado disponible
    Monitor disponible

    El producto "Ratón" no se muestra porque no tiene stock.


    15. Bucles anidados

    Un bucle anidado es un bucle dentro de otro bucle.

    Esto puede parecer complicado al principio, pero es muy útil para trabajar con tablas, matrices, calendarios, tableros de juego o estructuras de filas y columnas.

    Ejemplo sencillo:

    <?php
    for ($fila = 1; $fila <= 3; $fila++) {
    for ($columna = 1; $columna <= 3; $columna++) {
    echo "Fila " . $fila . ", Columna " . $columna . "<br>";
    }
    }
    ?>

    Resultado:

    Fila 1, Columna 1
    Fila 1, Columna 2
    Fila 1, Columna 3
    Fila 2, Columna 1
    Fila 2, Columna 2
    Fila 2, Columna 3
    Fila 3, Columna 1
    Fila 3, Columna 2
    Fila 3, Columna 3

    Por cada vuelta del bucle exterior, el bucle interior se ejecuta completo.

    Es decir:

    Primero estamos en la fila 1 y recorremos las columnas 1, 2 y 3.

    Luego pasamos a la fila 2 y volvemos a recorrer las columnas 1, 2 y 3.

    Después hacemos lo mismo con la fila 3.


    Ejemplo práctico: tabla de multiplicar completa

    <?php
    echo "<table border='1'>";

    for ($fila = 1; $fila <= 10; $fila++) {
    echo "<tr>";

    for ($columna = 1; $columna <= 10; $columna++) {
    echo "<td>" . ($fila * $columna) . "</td>";
    }

    echo "</tr>";
    }

    echo "</table>";
    ?>

    Este código genera una tabla de multiplicar del 1 al 10.

    El bucle exterior crea las filas.

    El bucle interior crea las columnas.

    Esta idea es muy parecida a recorrer una matriz.


    16. Alternar estilos con bucles

    Cuando generamos HTML con PHP, muchas veces queremos aplicar estilos diferentes según la posición de un elemento.

    Por ejemplo, podemos alternar filas pares e impares en una tabla.

    <?php
    $productos = ["Teclado", "Ratón", "Monitor", "Altavoces", "Webcam"];

    echo "<table border='1'>";

    for ($i = 0; $i < count($productos); $i++) {
    if ($i % 2 == 0) {
    echo "<tr style='background-color: #eeeeee;'>";
    } else {
    echo "<tr style='background-color: #ffffff;'>";
    }

    echo "<td>" . $productos[$i] . "</td>";
    echo "</tr>";
    }

    echo "</table>";
    ?>

    Este ejemplo demuestra que los bucles no solo sirven para repetir contenido, sino también para controlar cómo se presenta ese contenido.

    En proyectos reales, lo normal sería usar clases CSS en vez de estilos en línea, pero para entender la lógica el ejemplo es bastante claro.

    Una versión más limpia usando clases sería:

    <?php
    $productos = ["Teclado", "Ratón", "Monitor", "Altavoces", "Webcam"];

    echo "<table>";

    for ($i = 0; $i < count($productos); $i++) {
    if ($i % 2 == 0) {
    $clase = "par";
    } else {
    $clase = "impar";
    }

    echo "<tr class='" . $clase . "'>";
    echo "<td>" . $productos[$i] . "</td>";
    echo "</tr>";
    }

    echo "</table>";
    ?>

    Y en CSS podríamos tener:

    .par {
    background-color: #eeeeee;
    }

    .impar {
    background-color: #ffffff;
    }

    17. Generar formularios con bucles

    También podemos usar bucles para generar partes repetitivas de un formulario.

    Por ejemplo, crear un desplegable con los días del mes:

    <?php
    echo "<select name='dia'>";

    for ($dia = 1; $dia <= 31; $dia++) {
    echo "<option value='" . $dia . "'>" . $dia . "</option>";
    }

    echo "</select>";
    ?>

    Este código genera 31 opciones sin tener que escribirlas una por una.

    El HTML final sería equivalente a:

    <select name="dia">
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
    ...
    <option value="31">31</option>
    </select>

    Este tipo de generación dinámica es muy habitual para fechas, cantidades, años, categorías o filtros.


    Ejemplo práctico: selector de años

    <?php
    $anioActual = date("Y");

    echo "<select name='anio'>";

    for ($anio = $anioActual; $anio >= $anioActual - 10; $anio--) {
    echo "<option value='" . $anio . "'>" . $anio . "</option>";
    }

    echo "</select>";
    ?>

    La función date("Y") devuelve el año actual.

    Si estamos en 2026, generará opciones desde 2026 hasta 2016.


    18. Combinar bucles con formularios

    Vamos a ver un ejemplo algo más completo.

    Imaginemos que recibimos un número desde un formulario y queremos mostrar su tabla de multiplicar.

    Formulario HTML:

    <form method="post">
    <label>Introduce un número:</label>
    <input type="number" name="numero">

    <button type="submit">Mostrar tabla</button>
    </form>

    Código PHP:

    <?php
    if (isset($_POST["numero"])) {
    $numero = $_POST["numero"];

    echo "<h2>Tabla del " . $numero . "</h2>";

    for ($i = 1; $i <= 10; $i++) {
    echo $numero . " x " . $i . " = " . ($numero * $i) . "<br>";
    }
    }
    ?>

    Archivo completo:

    <!DOCTYPE html>
    <html lang="es">
    <head>
    <meta charset="UTF-8">
    <title>Tabla de multiplicar</title>
    </head>
    <body>

    <h1>Generador de tablas de multiplicar</h1>

    <form method="post">
    <label>Introduce un número:</label>
    <input type="number" name="numero">

    <button type="submit">Mostrar tabla</button>
    </form>

    <?php
    if (isset($_POST["numero"])) {
    $numero = $_POST["numero"];

    echo "<h2>Tabla del " . $numero . "</h2>";

    for ($i = 1; $i <= 10; $i++) {
    echo $numero . " x " . $i . " = " . ($numero * $i) . "<br>";
    }
    }
    ?>

    </body>
    </html>

    Este ejemplo ya se parece más a una pequeña aplicación web.

    El usuario introduce un dato, PHP lo recibe, procesa la información y genera una respuesta HTML.


    19. Ejemplo completo: listado de alumnos

    Vamos a crear un pequeño listado de alumnos con sus notas.

    <?php
    $alumnos = [
    [
    "nombre" => "Ana",
    "nota" => 8
    ],
    [
    "nombre" => "Luis",
    "nota" => 4
    ],
    [
    "nombre" => "Marta",
    "nota" => 6
    ],
    [
    "nombre" => "Carlos",
    "nota" => 3
    ]
    ];

    echo "<table border='1'>";
    echo "<tr>";
    echo "<th>Alumno</th>";
    echo "<th>Nota</th>";
    echo "<th>Resultado</th>";
    echo "</tr>";

    foreach ($alumnos as $alumno) {
    echo "<tr>";
    echo "<td>" . $alumno["nombre"] . "</td>";
    echo "<td>" . $alumno["nota"] . "</td>";

    if ($alumno["nota"] >= 5) {
    echo "<td>Aprobado</td>";
    } else {
    echo "<td>Suspenso</td>";
    }

    echo "</tr>";
    }

    echo "</table>";
    ?>

    Este ejemplo une varios conceptos:

    Arrays.

    foreach.

    Condicionales.

    Generación de tablas HTML.

    Acceso a datos asociativos.

    Es un ejemplo muy parecido a lo que podríamos hacer después con datos almacenados en una base de datos.


    20. Ejemplo completo: resumen de ventas

    Supongamos que tenemos varias ventas y queremos mostrar el total vendido.

    <?php
    $ventas = [
    [
    "producto" => "Teclado",
    "unidades" => 3,
    "precio" => 25
    ],
    [
    "producto" => "Ratón",
    "unidades" => 5,
    "precio" => 15
    ],
    [
    "producto" => "Monitor",
    "unidades" => 2,
    "precio" => 150
    ]
    ];

    $totalGeneral = 0;

    echo "<h1>Resumen de ventas</h1>";

    echo "<table border='1'>";
    echo "<tr>";
    echo "<th>Producto</th>";
    echo "<th>Unidades</th>";
    echo "<th>Precio</th>";
    echo "<th>Total</th>";
    echo "</tr>";

    foreach ($ventas as $venta) {
    $totalLinea = $venta["unidades"] * $venta["precio"];
    $totalGeneral += $totalLinea;

    echo "<tr>";
    echo "<td>" . $venta["producto"] . "</td>";
    echo "<td>" . $venta["unidades"] . "</td>";
    echo "<td>" . $venta["precio"] . " €</td>";
    echo "<td>" . $totalLinea . " €</td>";
    echo "</tr>";
    }

    echo "<tr>";
    echo "<td colspan='3'><strong>Total general</strong></td>";
    echo "<td><strong>" . $totalGeneral . " €</strong></td>";
    echo "</tr>";

    echo "</table>";
    ?>

    Este ejemplo es muy potente porque se parece a una factura, un carrito o un resumen de pedidos.

    El bucle recorre las ventas.

    En cada vuelta calcula el total de una línea.

    Después suma ese total al total general.

    Finalmente muestra el total acumulado.


    21. Errores habituales al trabajar con bucles

    Uno de los errores más comunes es olvidar actualizar la variable de control.

    <?php
    $i = 1;

    while ($i <= 10) {
    echo $i;
    }
    ?>

    Este código genera un bucle infinito porque $i nunca cambia.

    La versión correcta sería:

    <?php
    $i = 1;

    while ($i <= 10) {
    echo $i;
    $i++;
    }
    ?>

    Otro error común es equivocarse con la condición final.

    <?php
    for ($i = 1; $i < 10; $i++) {
    echo $i . "<br>";
    }
    ?>

    Este código muestra del 1 al 9, no del 1 al 10. Si queremos incluir el 10, la condición debe ser:

    $i <= 10

    También es habitual confundirse con los índices de los arrays.

    <?php
    $frutas = ["Manzana", "Pera", "Naranja"];

    for ($i = 1; $i <= count($frutas); $i++) {
    echo $frutas[$i] . "<br>";
    }
    ?>

    Este código tiene problemas porque el array empieza en la posición 0, no en la posición 1.

    La versión correcta sería:

    <?php
    $frutas = ["Manzana", "Pera", "Naranja"];

    for ($i = 0; $i < count($frutas); $i++) {
    echo $frutas[$i] . "<br>";
    }
    ?>

    22. Cuándo usar cada bucle

    • Aunque muchas veces podemos resolver el mismo problema con varios tipos de bucles, es importante elegir el más adecuado.
    • Usaremos while cuando no sepamos exactamente cuántas veces se va a repetir algo y dependamos de una condición.
    • Por ejemplo, mientras queden intentos, mientras no se encuentre un dato, mientras una variable no tenga cierto valor.
    • Usaremos do while cuando queramos que el bloque se ejecute al menos una vez.
    • Por ejemplo, un menú que debe mostrarse antes de comprobar si el usuario quiere salir.
    • Usaremos for cuando sepamos cuántas repeticiones queremos hacer.
    • Por ejemplo, mostrar los números del 1 al 100, generar una tabla de multiplicar o crear 31 opciones para los días de un mes.
    • Usaremos foreach cuando queramos recorrer arrays.
    • Por ejemplo, mostrar productos, alumnos, notas, usuarios, pedidos o cualquier lista de datos.
    • La decisión más común en PHP web será:
    • Si voy a contar, uso for.
    • Si voy a recorrer un array, uso foreach.
    • Si dependo de una condición, uso while.

    23. Tabla resumen de bucles en PHP

    BucleCuándo usarloEjemplo típico
    whileCuando se repite mientras una condición sea verdaderaReintentar una operación
    do whileCuando debe ejecutarse al menos una vezMostrar un menú
    forCuando conocemos el número de repeticionesTabla de multiplicar
    foreachCuando recorremos arraysListado de productos

    24. Práctica guiada: generador de tabla de multiplicar

    Vamos a crear una pequeña página en PHP que muestre la tabla de multiplicar de un número recibido por formulario.

    Archivo: tabla.php

    <!DOCTYPE html>
    <html lang="es">
    <head>
    <meta charset="UTF-8">
    <title>Tabla de multiplicar</title>
    </head>
    <body>

    <h1>Generador de tabla de multiplicar</h1>

    <form method="post">
    <label for="numero">Número:</label>
    <input type="number" name="numero" id="numero" required>

    <button type="submit">Generar</button>
    </form>

    <?php
    if (isset($_POST["numero"])) {
    $numero = $_POST["numero"];

    echo "<h2>Tabla del " . $numero . "</h2>";

    echo "<table border='1'>";
    echo "<tr>";
    echo "<th>Operación</th>";
    echo "<th>Resultado</th>";
    echo "</tr>";

    for ($i = 1; $i <= 10; $i++) {
    echo "<tr>";
    echo "<td>" . $numero . " x " . $i . "</td>";
    echo "<td>" . ($numero * $i) . "</td>";
    echo "</tr>";
    }

    echo "</table>";
    }
    ?>

    </body>
    </html>

    En esta práctica el alumno debe observar que el HTML inicial siempre se carga, pero la tabla solo aparece después de enviar el formulario.

    La condición:

    if (isset($_POST["numero"]))

    comprueba si el usuario ha enviado el formulario.

    El bucle:

    for ($i = 1; $i <= 10; $i++)

    genera las diez filas de la tabla.


    25. Práctica guiada: listado de productos con stock

    Vamos a crear una pequeña página que muestre productos, precios y disponibilidad.

    <!DOCTYPE html>
    <html lang="es">
    <head>
    <meta charset="UTF-8">
    <title>Listado de productos</title>
    </head>
    <body>

    <h1>Productos de la tienda</h1>

    <?php
    $productos = [
    [
    "nombre" => "Teclado mecánico",
    "precio" => 49.99,
    "stock" => 8
    ],
    [
    "nombre" => "Ratón inalámbrico",
    "precio" => 19.99,
    "stock" => 0
    ],
    [
    "nombre" => "Monitor 24 pulgadas",
    "precio" => 129.99,
    "stock" => 4
    ],
    [
    "nombre" => "Auriculares",
    "precio" => 35.50,
    "stock" => 0
    ]
    ];

    echo "<table border='1'>";
    echo "<tr>";
    echo "<th>Producto</th>";
    echo "<th>Precio</th>";
    echo "<th>Estado</th>";
    echo "</tr>";

    foreach ($productos as $producto) {
    echo "<tr>";
    echo "<td>" . $producto["nombre"] . "</td>";
    echo "<td>" . $producto["precio"] . " €</td>";

    if ($producto["stock"] > 0) {
    echo "<td>Disponible</td>";
    } else {
    echo "<td>Agotado</td>";
    }

    echo "</tr>";
    }

    echo "</table>";
    ?>

    </body>
    </html>

    Este ejercicio es muy útil porque combina datos, bucles, condicionales y salida HTML.

    Además, prepara al alumno para entender cómo se mostrarán registros obtenidos de una base de datos.


    26. Práctica guiada: resumen de notas de una clase

    En esta práctica vamos a calcular cuántos alumnos han aprobado, cuántos han suspendido y cuál es la nota media.

    <?php
    $notas = [8, 4, 7, 3, 9, 5, 6, 2];

    $aprobados = 0;
    $suspensos = 0;
    $suma = 0;

    foreach ($notas as $nota) {
    $suma += $nota;

    if ($nota >= 5) {
    $aprobados++;
    } else {
    $suspensos++;
    }
    }

    $media = $suma / count($notas);

    echo "<h1>Resumen de notas</h1>";
    echo "Número de alumnos: " . count($notas) . "<br>";
    echo "Aprobados: " . $aprobados . "<br>";
    echo "Suspensos: " . $suspensos . "<br>";
    echo "Nota media: " . $media . "<br>";
    ?>

    Este ejercicio trabaja tres ideas fundamentales:

    Recorrer una colección de datos.

    Contar elementos que cumplen una condición.

    Acumular valores para calcular un resultado final.


    27. Ejercicios propuestos

    Ejercicio 1

    Crea un programa en PHP que muestre los números del 1 al 50 usando un bucle for.

    Después modifica el programa para que solo muestre los números pares.


    Ejercicio 2

    Crea un programa que muestre una cuenta atrás desde 20 hasta 1 usando un bucle while.

    Al finalizar debe mostrar el mensaje:

    Fin de la cuenta atrás

    Ejercicio 3

    Crea un array con cinco nombres de compañeros de clase.

    Después recórrelo con foreach y muestra cada nombre dentro de una etiqueta <li>.

    El resultado debe ser una lista HTML.


    Ejercicio 4

    Crea un array con varias notas.

    El programa debe mostrar cada nota e indicar si está aprobada o suspensa.

    Después debe mostrar:

    • Número total de notas.
    • Número de aprobados.
    • Número de suspensos.
    • Nota media.

    Ejercicio 5

    Crea una tabla HTML de 10 filas usando un bucle for.

    La tabla debe tener dos columnas:

    NúmeroDoble

    Por ejemplo:

    NúmeroDoble
    12
    24
    36

    Ejercicio 6

    Crea un array de productos. Cada producto debe tener:

    • Nombre.
    • Precio.
    • Stock.

    Muestra los productos en una tabla HTML.

    Si el stock es mayor que cero, debe aparecer Disponible.

    Si el stock es cero, debe aparecer Agotado.


    Ejercicio 7

    Crea un programa que genere un desplegable <select> con los años desde 2020 hasta 2030.

    Cada año debe estar dentro de una etiqueta <option>.


    Ejercicio 8

    Crea una tabla de multiplicar completa del 1 al 10 usando bucles anidados.

    Debe mostrarse en una tabla HTML.


    28. Reto final del tema

    Crea una página llamada tienda.php.

    La página debe tener un array de productos con esta información:

    • Nombre del producto.
    • Categoría.
    • Precio.
    • Stock.

    La página debe mostrar una tabla con todos los productos.

    Además:

    Si el stock es mayor que cero, debe mostrar Disponible.

    Si el stock es cero, debe mostrar Agotado.

    Al final de la tabla debe mostrar:

    • Número total de productos.
    • Número de productos disponibles.
    • Número de productos agotados.
    • Valor total del inventario.

    El valor total del inventario se calcula multiplicando el precio de cada producto por su stock y sumando todos los resultados.

    Una posible base para empezar sería:

    <?php
    $productos = [
    [
    "nombre" => "Teclado",
    "categoria" => "Informática",
    "precio" => 25,
    "stock" => 10
    ],
    [
    "nombre" => "Ratón",
    "categoria" => "Informática",
    "precio" => 15,
    "stock" => 0
    ],
    [
    "nombre" => "Monitor",
    "categoria" => "Informática",
    "precio" => 150,
    "stock" => 4
    ],
    [
    "nombre" => "Silla",
    "categoria" => "Oficina",
    "precio" => 90,
    "stock" => 2
    ]
    ];
    ?>

    Este reto obliga a usar:

    foreach.

    Condicionales.

    Contadores.

    Acumuladores.

    Tablas HTML generadas con PHP.

    Es un ejercicio sencillo en apariencia, pero muy completo para consolidar el tema.


    29. Solución orientativa del reto final

    <!DOCTYPE html>
    <html lang="es">
    <head>
    <meta charset="UTF-8">
    <title>Tienda</title>
    </head>
    <body>

    <h1>Inventario de la tienda</h1>

    <?php
    $productos = [
    [
    "nombre" => "Teclado",
    "categoria" => "Informática",
    "precio" => 25,
    "stock" => 10
    ],
    [
    "nombre" => "Ratón",
    "categoria" => "Informática",
    "precio" => 15,
    "stock" => 0
    ],
    [
    "nombre" => "Monitor",
    "categoria" => "Informática",
    "precio" => 150,
    "stock" => 4
    ],
    [
    "nombre" => "Silla",
    "categoria" => "Oficina",
    "precio" => 90,
    "stock" => 2
    ]
    ];

    $totalProductos = count($productos);
    $productosDisponibles = 0;
    $productosAgotados = 0;
    $valorInventario = 0;

    echo "<table border='1'>";
    echo "<tr>";
    echo "<th>Nombre</th>";
    echo "<th>Categoría</th>";
    echo "<th>Precio</th>";
    echo "<th>Stock</th>";
    echo "<th>Estado</th>";
    echo "</tr>";

    foreach ($productos as $producto) {
    $valorProducto = $producto["precio"] * $producto["stock"];
    $valorInventario += $valorProducto;

    if ($producto["stock"] > 0) {
    $estado = "Disponible";
    $productosDisponibles++;
    } else {
    $estado = "Agotado";
    $productosAgotados++;
    }

    echo "<tr>";
    echo "<td>" . $producto["nombre"] . "</td>";
    echo "<td>" . $producto["categoria"] . "</td>";
    echo "<td>" . $producto["precio"] . " €</td>";
    echo "<td>" . $producto["stock"] . "</td>";
    echo "<td>" . $estado . "</td>";
    echo "</tr>";
    }

    echo "</table>";

    echo "<h2>Resumen</h2>";
    echo "Total de productos: " . $totalProductos . "<br>";
    echo "Productos disponibles: " . $productosDisponibles . "<br>";
    echo "Productos agotados: " . $productosAgotados . "<br>";
    echo "Valor total del inventario: " . $valorInventario . " €<br>";
    ?>

    </body>
    </html>

    Este ejemplo resume muy bien para qué sirven los bucles en PHP. No se trata solo de repetir código. Se trata de recorrer datos, analizarlos, tomar decisiones y construir una salida útil para el usuario.


    30. Conclusión

    Los bucles son una de las herramientas más importantes de cualquier lenguaje de programación. En PHP son especialmente útiles porque muchas veces necesitamos generar HTML a partir de datos.

    Con un bucle podemos mostrar listas, construir tablas, recorrer productos, calcular totales, validar información o analizar conjuntos de datos.

    • El while es útil cuando dependemos de una condición.
    • El do while garantiza que el bloque se ejecute al menos una vez.
    • El for es ideal cuando sabemos cuántas veces queremos repetir.
    • El foreach es la herramienta principal para recorrer arrays.

    Dominar los bucles es un paso fundamental antes de avanzar hacia arrays más complejos, formularios, bases de datos y aplicaciones web completas.