Autor: ciberkaos

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

  • 1.9 – Uso de include y require en PHP

    1.9 – Uso de include y require en PHP

    Introducción

    Cuando empezamos a crear páginas web con PHP, es habitual que al principio cada archivo tenga todo su código escrito dentro del mismo documento. Por ejemplo, podemos tener una página index.php, otra llamada contacto.php, otra llamada productos.php y otra llamada servicios.php. Cada una de ellas puede tener su propio HTML completo, con su cabecera, su menú, su contenido principal y su pie de página.

    El problema aparece cuando varias páginas comparten partes iguales. Imaginemos que todas las páginas tienen el mismo menú de navegación. Si escribimos ese menú directamente en cada archivo, estaremos repitiendo el mismo código una y otra vez. Esto puede parecer cómodo al principio, pero en cuanto el proyecto crece se convierte en un problema.

    Por ejemplo, si queremos añadir una nueva opción al menú, tendríamos que modificar manualmente todos los archivos del sitio web. Si tenemos cuatro páginas, todavía es manejable. Pero si tenemos veinte, cincuenta o cien páginas, mantener ese código repetido se vuelve lento, incómodo y muy propenso a errores.

    Para solucionar este problema, PHP nos permite separar partes comunes del código en archivos independientes y después insertarlas donde las necesitemos. Para eso usamos principalmente las instrucciones include y require.

    Estas instrucciones permiten cargar el contenido de un archivo dentro de otro. Dicho de forma sencilla, PHP lee el archivo indicado y coloca su contenido justo en el punto donde hemos escrito el include o el require.

    Esto es especialmente útil para crear partes reutilizables de una página web, como:

    • La cabecera HTML.
    • El menú de navegación.
    • El pie de página.
    • Barras laterales.
    • Formularios comunes.
    • Bloques de conexión a bases de datos.
    • Configuraciones compartidas.

    En este tema vamos a centrarnos en el uso más inicial y visual: reutilizar fragmentos HTML comunes en varias páginas PHP.


    El problema del código repetido

    Supongamos que tenemos una página sencilla llamada index.php.

    <!DOCTYPE html>
    <html lang="es">
    <head>
        <meta charset="UTF-8">
        <title>Mi página web</title>
    </head>
    <body>
    
        <header>
            <h1>Mi sitio web</h1>
        </header>
    
        <nav>
            <a href="index.php">Inicio</a>
            <a href="servicios.php">Servicios</a>
            <a href="contacto.php">Contacto</a>
        </nav>
    
        <main>
            <h2>Página de inicio</h2>
            <p>Bienvenido a mi página web.</p>
        </main>
    
        <footer>
            <p>&copy; 2026 - Mi sitio web</p>
        </footer>
    
    </body>
    </html>

    Ahora imaginemos que tenemos otra página llamada servicios.php.

    <!DOCTYPE html>
    <html lang="es">
    <head>
        <meta charset="UTF-8">
        <title>Servicios</title>
    </head>
    <body>
    
        <header>
            <h1>Mi sitio web</h1>
        </header>
    
        <nav>
            <a href="index.php">Inicio</a>
            <a href="servicios.php">Servicios</a>
            <a href="contacto.php">Contacto</a>
        </nav>
    
        <main>
            <h2>Nuestros servicios</h2>
            <p>En esta sección mostramos los servicios disponibles.</p>
        </main>
    
        <footer>
            <p>&copy; 2026 - Mi sitio web</p>
        </footer>
    
    </body>
    </html>

    Y otra página llamada contacto.php.

    <!DOCTYPE html>
    <html lang="es">
    <head>
        <meta charset="UTF-8">
        <title>Contacto</title>
    </head>
    <body>
    
        <header>
            <h1>Mi sitio web</h1>
        </header>
    
        <nav>
            <a href="index.php">Inicio</a>
            <a href="servicios.php">Servicios</a>
            <a href="contacto.php">Contacto</a>
        </nav>
    
        <main>
            <h2>Contacto</h2>
            <p>Puedes contactar con nosotros a través de esta página.</p>
        </main>
    
        <footer>
            <p>&copy; 2026 - Mi sitio web</p>
        </footer>
    
    </body>
    </html>

    Si observamos los tres archivos, vemos que hay mucho código repetido. La cabecera, el menú y el pie de página aparecen una y otra vez.

    Esto no es una buena práctica. Si queremos cambiar el título principal del sitio, modificar el menú o actualizar el pie de página, tendremos que hacerlo en todos los archivos.

    La solución consiste en separar esas partes comunes en archivos independientes.


    Qué es include

    La instrucción include permite insertar el contenido de un archivo dentro de otro archivo PHP.

    Su estructura básica es la siguiente:

    include "archivo.php";

    Cuando PHP encuentra esta línea, intenta buscar el archivo indicado y colocar su contenido en ese punto exacto.

    Por ejemplo:

    include "menu.php";

    Esto significa que PHP cargará el archivo menu.php y mostrará su contenido justo donde aparece el include.


    Crear un archivo común para el menú

    Vamos a separar el menú de navegación en un archivo independiente.

    Creamos un archivo llamado menu.php.

    <nav>
        <a href="index.php">Inicio</a>
        <a href="servicios.php">Servicios</a>
        <a href="contacto.php">Contacto</a>
    </nav>

    Este archivo no necesita tener una estructura HTML completa. No necesita <!DOCTYPE html>, ni <html>, ni <head>, ni <body>, porque no representa una página completa. Solo contiene una parte de la página.

    Ahora podemos utilizarlo dentro de index.php.

    <!DOCTYPE html>
    <html lang="es">
    <head>
        <meta charset="UTF-8">
        <title>Mi página web</title>
    </head>
    <body>
    
        <header>
            <h1>Mi sitio web</h1>
        </header>
    
        <?php include "menu.php"; ?>
    
        <main>
            <h2>Página de inicio</h2>
            <p>Bienvenido a mi página web.</p>
        </main>
    
        <footer>
            <p>&copy; 2026 - Mi sitio web</p>
        </footer>
    
    </body>
    </html>

    El resultado en el navegador será el mismo que antes. La diferencia importante es que ahora el menú está guardado en un único archivo.

    Podemos hacer lo mismo en servicios.php.

    <!DOCTYPE html>
    <html lang="es">
    <head>
        <meta charset="UTF-8">
        <title>Servicios</title>
    </head>
    <body>
    
        <header>
            <h1>Mi sitio web</h1>
        </header>
    
        <?php include "menu.php"; ?>
    
        <main>
            <h2>Nuestros servicios</h2>
            <p>En esta sección mostramos los servicios disponibles.</p>
        </main>
    
        <footer>
            <p>&copy; 2026 - Mi sitio web</p>
        </footer>
    
    </body>
    </html>

    Y también en contacto.php.

    <!DOCTYPE html>
    <html lang="es">
    <head>
        <meta charset="UTF-8">
        <title>Contacto</title>
    </head>
    <body>
    
        <header>
            <h1>Mi sitio web</h1>
        </header>
    
        <?php include "menu.php"; ?>
    
        <main>
            <h2>Contacto</h2>
            <p>Puedes contactar con nosotros a través de esta página.</p>
        </main>
    
        <footer>
            <p>&copy; 2026 - Mi sitio web</p>
        </footer>
    
    </body>
    </html>

    Ahora, si queremos modificar el menú, solo tenemos que cambiar el archivo menu.php. Todas las páginas que lo incluyan mostrarán automáticamente el menú actualizado.


    Separar también la cabecera y el pie de página

    El menú no es la única parte que podemos reutilizar. También podemos separar la cabecera y el pie.

    Creamos un archivo llamado header.php.

    <header>
        <h1>Mi sitio web</h1>
    </header>

    Creamos otro archivo llamado footer.php.

    <footer>
        <p>&copy; 2026 - Mi sitio web</p>
    </footer>

    Ahora nuestra página index.php queda más limpia.

    <!DOCTYPE html>
    <html lang="es">
    <head>
        <meta charset="UTF-8">
        <title>Mi página web</title>
    </head>
    <body>
    
        <?php include "header.php"; ?>
    
        <?php include "menu.php"; ?>
    
        <main>
            <h2>Página de inicio</h2>
            <p>Bienvenido a mi página web.</p>
        </main>
    
        <?php include "footer.php"; ?>
    
    </body>
    </html>

    La página sigue funcionando igual, pero ahora está mejor organizada. Cada parte común está en su propio archivo.

    Esta forma de trabajar es muy habitual en proyectos web. Permite dividir una página en piezas pequeñas, más fáciles de entender, mantener y reutilizar.


    Una estructura básica de carpetas

    Cuando un proyecto empieza a crecer, conviene organizar los archivos en carpetas.

    Podemos crear una carpeta llamada includes para guardar los fragmentos comunes.

    La estructura podría ser esta:

    mi-proyecto/
    │
    ├── index.php
    ├── servicios.php
    ├── contacto.php
    │
    └── includes/
        ├── header.php
        ├── menu.php
        └── footer.php

    En este caso, como los archivos comunes están dentro de la carpeta includes, tenemos que indicar la ruta correctamente.

    En index.php escribiríamos:

    <?php include "includes/header.php"; ?>
    
    <?php include "includes/menu.php"; ?>
    
    <?php include "includes/footer.php"; ?>

    La página completa quedaría así:

    <!DOCTYPE html>
    <html lang="es">
    <head>
        <meta charset="UTF-8">
        <title>Mi página web</title>
    </head>
    <body>
    
        <?php include "includes/header.php"; ?>
    
        <?php include "includes/menu.php"; ?>
    
        <main>
            <h2>Página de inicio</h2>
            <p>Bienvenido a mi página web.</p>
        </main>
    
        <?php include "includes/footer.php"; ?>
    
    </body>
    </html>

    Es importante entender que la ruta del archivo incluido depende de dónde se encuentra el archivo que está haciendo el include.

    Si index.php está en la raíz del proyecto y header.php está dentro de la carpeta includes, la ruta correcta será:

    include "includes/header.php";

    Qué ocurre si el archivo no existe

    Si usamos include y el archivo indicado no existe, PHP mostrará un aviso, pero intentará seguir ejecutando el resto de la página.

    Por ejemplo:

    <?php include "includes/cabecera.php"; ?>

    Si el archivo cabecera.php no existe, PHP generará un mensaje de advertencia similar a este:

    Warning: include(includes/cabecera.php): Failed to open stream...

    Aunque aparezca el aviso, PHP intentará continuar con el resto del documento.

    Esto puede ser útil en algunos casos, pero también puede ser peligroso si el archivo incluido es fundamental para que la página funcione correctamente.


    Qué es require

    La instrucción require también sirve para insertar el contenido de un archivo dentro de otro. Su uso es muy parecido al de include.

    require "archivo.php";

    La diferencia principal está en lo que ocurre si el archivo no se encuentra.

    Con include, PHP muestra una advertencia y continúa ejecutando la página.

    Con require, PHP muestra un error grave y detiene la ejecución.

    Por ejemplo:

    <?php require "includes/header.php"; ?>

    Si el archivo existe, se carga normalmente. Pero si no existe, PHP detiene la página.

    Esto tiene sentido cuando el archivo que estamos cargando es imprescindible.


    Diferencia entre include y require

    Aunque las dos instrucciones sirven para cargar archivos externos, no se comportan igual cuando hay un problema.

    include se suele usar cuando el archivo que estamos cargando no es totalmente imprescindible. Si falla, la página puede seguir funcionando, aunque quizá no se muestre una parte concreta.

    require se usa cuando el archivo es necesario para que la página funcione correctamente. Si el archivo no existe, lo mejor es detener la ejecución para evitar errores mayores.

    Por ejemplo, en una página sencilla podríamos usar include para cargar un bloque visual como un aviso o una sección secundaria.

    <?php include "includes/aviso.php"; ?>

    Pero si en un proyecto más avanzado tenemos un archivo con la conexión a la base de datos, normalmente usaríamos require.

    <?php require "includes/conexion.php"; ?>

    En este tema estamos trabajando principalmente con HTML común, por lo que podemos empezar usando include. Más adelante, cuando trabajemos con configuración, sesiones, funciones o bases de datos, veremos que require puede ser más adecuado.


    include_once y require_once

    PHP también ofrece dos variantes muy utilizadas:

    include_once "archivo.php";
    require_once "archivo.php";

    La palabra once significa “una vez”. Estas instrucciones cargan el archivo solo si no se ha cargado antes.

    Esto es útil para evitar que el mismo archivo se incluya varias veces por error.

    Por ejemplo:

    <?php include_once "includes/menu.php"; ?>

    Si el archivo menu.php ya se ha cargado antes, PHP no lo volverá a cargar.

    Al principio, trabajando con cabeceras, menús y pies de página, normalmente nos bastará con include. Pero es importante conocer include_once y require_once, porque son muy habituales en proyectos más grandes.


    Crear una plantilla básica reutilizable

    Vamos a crear una estructura sencilla para una web con varias páginas.

    Tendremos esta organización:

    web/
    │
    ├── index.php
    ├── servicios.php
    ├── contacto.php
    │
    ├── css/
    │   └── estilos.css
    │
    └── includes/
        ├── header.php
        ├── menu.php
        └── footer.php

    Primero creamos el archivo includes/header.php.

    <header>
        <h1>Mi sitio web con PHP</h1>
        <p>Aprendiendo a reutilizar partes comunes de una página</p>
    </header>

    Ahora creamos el archivo includes/menu.php.

    <nav>
        <a href="index.php">Inicio</a>
        <a href="servicios.php">Servicios</a>
        <a href="contacto.php">Contacto</a>
    </nav>

    Después creamos el archivo includes/footer.php.

    <footer>
        <p>&copy; 2026 - Mi sitio web con PHP</p>
    </footer>

    Podemos añadir un archivo CSS sencillo en css/estilos.css.

    body {
        font-family: Arial, sans-serif;
        margin: 0;
        background-color: #f4f4f4;
    }
    
    header {
        background-color: #222;
        color: white;
        padding: 20px;
        text-align: center;
    }
    
    nav {
        background-color: #444;
        padding: 10px;
        text-align: center;
    }
    
    nav a {
        color: white;
        text-decoration: none;
        margin: 0 15px;
    }
    
    main {
        background-color: white;
        width: 80%;
        margin: 30px auto;
        padding: 20px;
        min-height: 300px;
    }
    
    footer {
        background-color: #222;
        color: white;
        text-align: center;
        padding: 15px;
    }

    Ahora creamos la página index.php.

    <!DOCTYPE html>
    <html lang="es">
    <head>
        <meta charset="UTF-8">
        <title>Inicio</title>
        <link rel="stylesheet" href="css/estilos.css">
    </head>
    <body>
    
        <?php include "includes/header.php"; ?>
    
        <?php include "includes/menu.php"; ?>
    
        <main>
            <h2>Inicio</h2>
            <p>Esta es la página principal de nuestro sitio web.</p>
            <p>El encabezado, el menú y el pie de página se cargan desde archivos externos.</p>
        </main>
    
        <?php include "includes/footer.php"; ?>
    
    </body>
    </html>

    Creamos también la página servicios.php.

    <!DOCTYPE html>
    <html lang="es">
    <head>
        <meta charset="UTF-8">
        <title>Servicios</title>
        <link rel="stylesheet" href="css/estilos.css">
    </head>
    <body>
    
        <?php include "includes/header.php"; ?>
    
        <?php include "includes/menu.php"; ?>
    
        <main>
            <h2>Servicios</h2>
            <p>En esta sección se mostrarían los servicios ofrecidos por la empresa o el proyecto.</p>
        </main>
    
        <?php include "includes/footer.php"; ?>
    
    </body>
    </html>

    Y finalmente la página contacto.php.

    <!DOCTYPE html>
    <html lang="es">
    <head>
        <meta charset="UTF-8">
        <title>Contacto</title>
        <link rel="stylesheet" href="css/estilos.css">
    </head>
    <body>
    
        <?php include "includes/header.php"; ?>
    
        <?php include "includes/menu.php"; ?>
    
        <main>
            <h2>Contacto</h2>
            <p>Desde esta página se podría mostrar un formulario de contacto.</p>
        </main>
    
        <?php include "includes/footer.php"; ?>
    
    </body>
    </html>

    Con esta estructura ya tenemos una pequeña web dividida en partes reutilizables.

    Si ahora queremos añadir una opción nueva al menú, solo tenemos que editar includes/menu.php.

    Por ejemplo:

    <nav>
        <a href="index.php">Inicio</a>
        <a href="servicios.php">Servicios</a>
        <a href="contacto.php">Contacto</a>
        <a href="blog.php">Blog</a>
    </nav>

    Automáticamente, todas las páginas que incluyan menu.php mostrarán la nueva opción.


    Incluir archivos que contienen HTML y PHP

    Los archivos incluidos no tienen por qué contener solo HTML. También pueden contener código PHP.

    Por ejemplo, podemos hacer que el footer muestre automáticamente el año actual.

    Archivo includes/footer.php:

    <footer>
        <p>&copy; <?php echo date("Y"); ?> - Mi sitio web con PHP</p>
    </footer>

    Ahora no tenemos que cambiar manualmente el año cada vez que empiece uno nuevo. PHP lo calculará automáticamente.

    Esto demuestra una de las ventajas de usar archivos .php para nuestros bloques comunes: pueden combinar HTML y código PHP.


    Usar variables antes de incluir un archivo

    También podemos preparar una variable en la página principal y usarla dentro de un archivo incluido.

    Por ejemplo, podemos crear una variable llamada $tituloPagina.

    En index.php:

    <?php
    $tituloPagina = "Inicio";
    ?>
    
    <!DOCTYPE html>
    <html lang="es">
    <head>
        <meta charset="UTF-8">
        <title><?php echo $tituloPagina; ?></title>
        <link rel="stylesheet" href="css/estilos.css">
    </head>
    <body>
    
        <?php include "includes/header.php"; ?>
    
        <?php include "includes/menu.php"; ?>
    
        <main>
            <h2><?php echo $tituloPagina; ?></h2>
            <p>Bienvenido a la página principal.</p>
        </main>
    
        <?php include "includes/footer.php"; ?>
    
    </body>
    </html>

    También podríamos usar esa variable dentro de header.php.

    Archivo includes/header.php:

    <header>
        <h1>Mi sitio web con PHP</h1>
        <p>Estás visitando la sección: <?php echo $tituloPagina; ?></p>
    </header>

    Cuando index.php incluye header.php, el archivo incluido puede acceder a la variable $tituloPagina, porque se está insertando dentro del mismo contexto de ejecución.

    Esto es muy útil, pero también exige orden. Si una variable se usa dentro de un archivo incluido, debemos asegurarnos de que se ha creado antes de hacer el include.


    Ejemplo con varias páginas y título dinámico

    Podemos aplicar la misma idea en todas las páginas.

    Archivo index.php:

    <?php
    $tituloPagina = "Inicio";
    ?>
    
    <!DOCTYPE html>
    <html lang="es">
    <head>
        <meta charset="UTF-8">
        <title><?php echo $tituloPagina; ?></title>
        <link rel="stylesheet" href="css/estilos.css">
    </head>
    <body>
    
        <?php include "includes/header.php"; ?>
        <?php include "includes/menu.php"; ?>
    
        <main>
            <h2><?php echo $tituloPagina; ?></h2>
            <p>Bienvenido a la página principal.</p>
        </main>
    
        <?php include "includes/footer.php"; ?>
    
    </body>
    </html>

    Archivo servicios.php:

    <?php
    $tituloPagina = "Servicios";
    ?>
    
    <!DOCTYPE html>
    <html lang="es">
    <head>
        <meta charset="UTF-8">
        <title><?php echo $tituloPagina; ?></title>
        <link rel="stylesheet" href="css/estilos.css">
    </head>
    <body>
    
        <?php include "includes/header.php"; ?>
        <?php include "includes/menu.php"; ?>
    
        <main>
            <h2><?php echo $tituloPagina; ?></h2>
            <p>Aquí puedes consultar nuestros servicios.</p>
        </main>
    
        <?php include "includes/footer.php"; ?>
    
    </body>
    </html>

    Archivo contacto.php:

    <?php
    $tituloPagina = "Contacto";
    ?>
    
    <!DOCTYPE html>
    <html lang="es">
    <head>
        <meta charset="UTF-8">
        <title><?php echo $tituloPagina; ?></title>
        <link rel="stylesheet" href="css/estilos.css">
    </head>
    <body>
    
        <?php include "includes/header.php"; ?>
        <?php include "includes/menu.php"; ?>
    
        <main>
            <h2><?php echo $tituloPagina; ?></h2>
            <p>Puedes contactar con nosotros desde esta sección.</p>
        </main>
    
        <?php include "includes/footer.php"; ?>
    
    </body>
    </html>

    Archivo includes/header.php:

    <header>
        <h1>Mi sitio web con PHP</h1>
        <p>Sección actual: <?php echo $tituloPagina; ?></p>
    </header>

    Con este ejemplo, cada página define su propio título, pero todas comparten la misma cabecera, el mismo menú y el mismo pie.


    Cuidado con las rutas

    Uno de los errores más habituales al usar include y require tiene que ver con las rutas de los archivos.

    Supongamos que tenemos esta estructura:

    web/
    │
    ├── index.php
    │
    ├── includes/
    │   └── menu.php
    │
    └── paginas/
        └── contacto.php

    Desde index.php, para incluir el menú, la ruta sería:

    <?php include "includes/menu.php"; ?>

    Pero desde paginas/contacto.php, esa ruta ya no sería correcta, porque contacto.php está dentro de la carpeta paginas.

    Desde ahí, primero tenemos que subir un nivel con ../ y luego entrar en includes.

    <?php include "../includes/menu.php"; ?>

    El símbolo ../ significa “subir a la carpeta superior”.

    Este detalle es importante. Muchas veces, cuando un include falla, no es porque el archivo esté mal, sino porque la ruta indicada no es correcta.


    Buenas prácticas iniciales

    Cuando empezamos a trabajar con include y require, conviene seguir una organización clara.

    Una buena práctica es guardar los archivos reutilizables dentro de una carpeta específica, por ejemplo includes, partials o templates.

    Por ejemplo:

    includes/
    ├── header.php
    ├── menu.php
    ├── footer.php
    └── sidebar.php

    También conviene usar nombres claros. Un archivo llamado header.php se entiende mejor que uno llamado parte1.php. Un archivo llamado menu.php se entiende mejor que uno llamado navegacion2.php.

    Otra recomendación importante es no abusar de los includes. Separar el código ayuda, pero si dividimos demasiado una página en muchos archivos pequeños sin necesidad, el proyecto puede volverse confuso. La idea es separar aquello que realmente se repite o que tiene sentido mantener de forma independiente.

    En esta etapa inicial, lo más recomendable es usar include para partes visuales comunes como header.php, menu.php y footer.php.

    Más adelante, cuando empecemos a trabajar con funciones, configuración, sesiones o bases de datos, tendrá sentido usar require o require_once para archivos imprescindibles.


    Resumen práctico

    include y require permiten cargar un archivo dentro de otro archivo PHP.

    La instrucción include intenta cargar el archivo y, si no lo encuentra, muestra una advertencia pero permite que la página continúe ejecutándose.

    La instrucción require también carga un archivo, pero si no lo encuentra detiene la ejecución de la página.

    En proyectos web, estas instrucciones son muy útiles para evitar repetir código. Podemos crear archivos comunes como header.php, menu.php y footer.php, e incluirlos en todas las páginas que los necesiten.

    Gracias a esto, nuestro proyecto queda más limpio, más ordenado y más fácil de mantener.


    Actividad propuesta

    Crea una pequeña web en PHP con tres páginas:

    • index.php
    • servicios.php
    • contacto.php

    La web debe tener una carpeta llamada includes con los siguientes archivos:

    • header.php
    • menu.php
    • footer.php

    Cada página debe cargar esos archivos usando include.

    Además, cada página debe tener un contenido principal diferente dentro de la etiqueta <main>.

    Como ampliación, crea una variable $tituloPagina en cada página y úsala para mostrar el título correspondiente tanto en la etiqueta <title> como dentro del contenido principal.


    Preguntas de reflexión

    ¿Por qué no es recomendable copiar y pegar el mismo menú en todas las páginas de un sitio web?

    ¿Qué ventaja tiene guardar el menú en un archivo independiente?

    ¿Qué diferencia hay entre include y require?

    ¿Qué ocurre si usamos include y el archivo no existe?

    ¿Qué ocurre si usamos require y el archivo no existe?

    ¿Para qué podría servir include_once?

    ¿Por qué es importante organizar correctamente las carpetas de un proyecto?

    ¿Qué problemas pueden aparecer si indicamos mal la ruta de un archivo incluido?


    Ejercicio final guiado

    Crea un proyecto llamado web_includes.

    Dentro del proyecto, crea esta estructura:

    web_includes/
    │
    ├── index.php
    ├── servicios.php
    ├── contacto.php
    │
    ├── css/
    │   └── estilos.css
    │
    └── includes/
        ├── header.php
        ├── menu.php
        └── footer.php

    En header.php, escribe la cabecera común del sitio.

    <header>
        <h1>Web creada con PHP</h1>
        <p>Ejemplo de reutilización de código con includes</p>
    </header>

    En menu.php, escribe el menú común.

    <nav>
        <a href="index.php">Inicio</a>
        <a href="servicios.php">Servicios</a>
        <a href="contacto.php">Contacto</a>
    </nav>

    En footer.php, escribe el pie común.

    <footer>
        <p>&copy; <?php echo date("Y"); ?> - Proyecto de clase</p>
    </footer>

    En css/estilos.css, añade unos estilos básicos.

    body {
        font-family: Arial, sans-serif;
        margin: 0;
        background-color: #eeeeee;
    }
    
    header {
        background-color: #1f2937;
        color: white;
        padding: 20px;
        text-align: center;
    }
    
    nav {
        background-color: #374151;
        padding: 10px;
        text-align: center;
    }
    
    nav a {
        color: white;
        margin: 0 10px;
        text-decoration: none;
    }
    
    main {
        background-color: white;
        margin: 30px auto;
        padding: 20px;
        width: 80%;
    }
    
    footer {
        background-color: #1f2937;
        color: white;
        text-align: center;
        padding: 15px;
    }

    En index.php, escribe:

    <?php
    $tituloPagina = "Inicio";
    ?>
    
    <!DOCTYPE html>
    <html lang="es">
    <head>
        <meta charset="UTF-8">
        <title><?php echo $tituloPagina; ?></title>
        <link rel="stylesheet" href="css/estilos.css">
    </head>
    <body>
    
        <?php include "includes/header.php"; ?>
        <?php include "includes/menu.php"; ?>
    
        <main>
            <h2><?php echo $tituloPagina; ?></h2>
            <p>Esta es la página principal del proyecto.</p>
        </main>
    
        <?php include "includes/footer.php"; ?>
    
    </body>
    </html>

    En servicios.php, escribe:

    <?php
    $tituloPagina = "Servicios";
    ?>
    
    <!DOCTYPE html>
    <html lang="es">
    <head>
        <meta charset="UTF-8">
        <title><?php echo $tituloPagina; ?></title>
        <link rel="stylesheet" href="css/estilos.css">
    </head>
    <body>
    
        <?php include "includes/header.php"; ?>
        <?php include "includes/menu.php"; ?>
    
        <main>
            <h2><?php echo $tituloPagina; ?></h2>
            <p>En esta página se describen los servicios ofrecidos.</p>
        </main>
    
        <?php include "includes/footer.php"; ?>
    
    </body>
    </html>

    En contacto.php, escribe:

    <?php
    $tituloPagina = "Contacto";
    ?>
    
    <!DOCTYPE html>
    <html lang="es">
    <head>
        <meta charset="UTF-8">
        <title><?php echo $tituloPagina; ?></title>
        <link rel="stylesheet" href="css/estilos.css">
    </head>
    <body>
    
        <?php include "includes/header.php"; ?>
        <?php include "includes/menu.php"; ?>
    
        <main>
            <h2><?php echo $tituloPagina; ?></h2>
            <p>Desde esta página se podría contactar con el sitio web.</p>
        </main>
    
        <?php include "includes/footer.php"; ?>
    
    </body>
    </html>

    Cuando hayas terminado, abre el proyecto desde un servidor local como XAMPP, MAMP o un contenedor con Apache y PHP. Comprueba que las tres páginas muestran la misma cabecera, el mismo menú y el mismo pie de página.

    Después modifica el archivo menu.php añadiendo una nueva opción llamada Blog.

    <nav>
        <a href="index.php">Inicio</a>
        <a href="servicios.php">Servicios</a>
        <a href="contacto.php">Contacto</a>
        <a href="blog.php">Blog</a>
    </nav>

    Comprueba que el cambio aparece automáticamente en todas las páginas.

    Ese es el objetivo principal de este tema: aprender a reutilizar código común para evitar repeticiones y facilitar el mantenimiento de una web.

  • Montar Google Drive como una unidad en Ubuntu sin sincronizar archivos

    Montar Google Drive como una unidad en Ubuntu sin sincronizar archivos

    1. Introducción

    En esta práctica vamos a aprender a montar Google Drive en Ubuntu como si fuera una unidad del sistema, pero sin sincronizar todos los archivos en el disco duro.

    Esto significa que podremos acceder a los archivos de Google Drive desde el explorador de archivos de Ubuntu, o desde la terminal, pero los archivos no se descargarán todos automáticamente. Se irán leyendo bajo demanda cuando los abramos o los copiemos.

    Para conseguirlo usaremos una herramienta llamada rclone.


    2. Objetivos de la práctica

    Al finalizar esta práctica, el alumno será capaz de:

    • Instalar rclone en Ubuntu.
    • Configurar una cuenta de Google Drive en rclone.
    • Montar Google Drive como una carpeta local.
    • Acceder a los archivos de Drive desde Ubuntu sin sincronizarlos.
    • Desmontar la unidad cuando sea necesario.
    • Crear un servicio para montar Google Drive automáticamente al iniciar sesión.

    3. Requisitos previos

    Para realizar esta práctica necesitas:

    • Un equipo con Ubuntu instalado.
    • Conexión a Internet.
    • Una cuenta de Google Drive.
    • Acceso a la terminal.
    • Permisos de administrador en el sistema.

    4. ¿Qué es rclone?

    rclone es una herramienta de línea de comandos que permite trabajar con servicios de almacenamiento en la nube como:

    • Google Drive.
    • OneDrive.
    • Dropbox.
    • Mega.
    • Amazon S3.
    • Nextcloud.
    • WebDAV.

    En esta práctica lo usaremos para montar Google Drive como una unidad, no para sincronizarlo.

    La diferencia es importante:

    OpciónQué hace
    SincronizarDescarga y mantiene copias locales de los archivos
    MontarMuestra los archivos como si estuvieran en local, pero se accede a ellos bajo demanda

    5. Instalación de rclone

    Abrimos una terminal y actualizamos la lista de paquetes:

    sudo apt update

    Instalamos rclone y fuse3:

    sudo apt install rclone fuse3

    fuse3 permite que un usuario pueda montar sistemas de archivos virtuales, como en este caso Google Drive.

    Comprobamos que rclone se ha instalado correctamente:

    rclone version

    Deberíamos ver una salida parecida a esta:

    rclone v1.xx.x
    - os/version: ubuntu
    - os/kernel: linux
    - os/type: linux

    6. Configuración de Google Drive en rclone

    Ahora vamos a configurar la conexión con nuestra cuenta de Google Drive.

    Ejecutamos:

    rclone config

    Aparecerá un menú en la terminal.

    Como todavía no tenemos ninguna conexión configurada, elegimos la opción:

    n

    Esta opción significa:

    New remote

    Es decir, crear una nueva conexión remota.


    6.1. Nombre de la conexión

    Cuando pregunte por el nombre, escribimos:

    gdrive

    Podríamos poner otro nombre, pero para esta práctica usaremos gdrive.

    Este nombre será el identificador que usaremos más adelante para referirnos a nuestro Google Drive.


    6.2. Selección del tipo de almacenamiento

    Después aparecerá una lista con muchos servicios de almacenamiento.

    Buscamos la opción correspondiente a:

    Google Drive

    El número puede cambiar según la versión de rclone, así que no copies el número de otra guía sin mirar la lista.

    Escribe el número que corresponda a Google Drive y pulsa Enter.


    6.3. Client ID y Client Secret

    rclone nos preguntará por:

    client_id
    client_secret

    Para una práctica normal podemos dejarlos vacíos pulsando Enter.

    Esto usará la configuración genérica de rclone.

    Si te pregunta algo mas que no sea scope dale a enter.


    6.4. Scope o permisos de acceso

    Cuando pregunte por el tipo de permisos o scope, elegimos la opción que permita acceso completo a Google Drive.

    Normalmente aparece como:

    drive

    Esto permite leer y escribir archivos en Google Drive desde Ubuntu.


    6.5. Configuración avanzada

    Cuando pregunte si queremos configuración avanzada:

    Edit advanced config?

    Respondemos:

    n

    6.6. Autenticación con Google

    Cuando pregunte:

    Use auto config?

    Si estamos en un Ubuntu con entorno gráfico, respondemos:

    y

    Se abrirá el navegador web para iniciar sesión con nuestra cuenta de Google.

    Aceptamos los permisos solicitados por rclone.

    Cuando el proceso termine, volvemos a la terminal.


    6.7. Guardar configuración

    Al final, rclone mostrará un resumen de la configuración.

    Cuando pregunte si queremos guardar la conexión, respondemos:

    y

    Después salimos del menú de configuración con:

    q

    7. Comprobar que la conexión funciona

    Para comprobar que podemos acceder a Google Drive, ejecutamos:

    rclone lsd gdrive:

    Este comando lista las carpetas principales de Google Drive.

    Si todo ha ido bien, veremos algo parecido a:

              -1 2026-05-25 10:30:00        -1 Documentos
    -1 2026-05-25 10:30:00 -1 Copias
    -1 2026-05-25 10:30:00 -1 Fotos

    Si aparece un error de autenticación, probablemente haya que repetir la configuración con:

    rclone config

    8. Crear la carpeta de montaje

    Ahora vamos a crear una carpeta local donde aparecerá Google Drive.

    Ejecutamos:

    mkdir -p ~/GoogleDrive

    Esta carpeta estará en nuestro directorio personal.

    La ruta completa será algo parecido a:

    /home/usuario/GoogleDrive

    Por ejemplo, si el usuario se llama antonio, la ruta será:

    /home/antonio/GoogleDrive

    9. Montar Google Drive como unidad

    Ahora montamos Google Drive dentro de esa carpeta:

    rclone mount gdrive: ~/GoogleDrive \
    --vfs-cache-mode writes \
    --daemon

    Explicación del comando:

    ParteSignificado
    rclone mountMonta un almacenamiento remoto
    gdrive:Nombre de la conexión configurada
    ~/GoogleDriveCarpeta local donde se montará
    --vfs-cache-mode writesUsa caché para operaciones de escritura
    --daemonEjecuta el montaje en segundo plano

    9.1. Comprobar el montaje

    Podemos comprobarlo desde la terminal:

    ls ~/GoogleDrive

    También podemos abrir el explorador de archivos de Ubuntu y entrar en la carpeta:

    GoogleDrive

    Ahí deberían aparecer los archivos y carpetas de nuestra cuenta de Google Drive.


    10. Importante: esto no sincroniza todos los archivos

    Este punto es clave.

    Con este sistema, Google Drive aparece como una carpeta local, pero no se descargan todos los archivos al ordenador.

    Los archivos se consultan cuando se necesitan.

    Por ejemplo:

    • Si abres un documento, se descargará temporalmente para poder leerlo.
    • Si copias un archivo desde Google Drive a otra carpeta local, entonces sí se descargará.
    • Si copias un archivo desde Ubuntu hacia ~/GoogleDrive, se subirá a Google Drive.
    • Si no abres un archivo, no ocupa espacio real en tu disco como una sincronización completa.

    11. Desmontar Google Drive

    Cuando queramos desmontar la unidad, usamos:

    fusermount3 -u ~/GoogleDrive

    Después de esto, la carpeta ~/GoogleDrive seguirá existiendo, pero ya no mostrará el contenido de Google Drive.

    Para comprobarlo:

    ls ~/GoogleDrive

    Si está desmontada, normalmente aparecerá vacía.


    12. Montaje automático al iniciar sesión

    Hasta ahora hemos montado Google Drive manualmente.

    Si queremos que se monte automáticamente al iniciar sesión en Ubuntu, podemos crear un servicio de usuario con systemd.


    12.1. Crear carpeta para servicios de usuario

    Ejecutamos:

    mkdir -p ~/.config/systemd/user

    12.2. Crear el archivo del servicio

    Creamos el archivo:

    nano ~/.config/systemd/user/rclone-gdrive.service

    Pegamos el siguiente contenido.

    Importante: cambia antonio por el nombre real de tu usuario en Ubuntu.

    [Unit]
    Description=Montar Google Drive con rclone
    After=network-online.target

    [Service]
    Type=simple
    ExecStart=/usr/bin/rclone mount gdrive: /home/antonio/GoogleDrive --vfs-cache-mode writes
    ExecStop=/bin/fusermount3 -u /home/antonio/GoogleDrive
    Restart=on-failure
    RestartSec=10

    [Install]
    WantedBy=default.target

    Guardamos el archivo:

    • Ctrl + O
    • Enter
    • Ctrl + X

    12.3. Activar el servicio

    Recargamos los servicios de usuario:

    systemctl --user daemon-reload

    Activamos el servicio para que arranque automáticamente:

    systemctl --user enable rclone-gdrive

    Iniciamos el servicio:

    systemctl --user start rclone-gdrive

    12.4. Comprobar el estado del servicio

    Ejecutamos:

    systemctl --user status rclone-gdrive

    Si todo está bien, deberíamos ver algo parecido a:

    Active: active (running)

    Para salir de la pantalla de estado, pulsamos:

    q

    13. Detener el montaje automático

    Si queremos parar el servicio temporalmente:

    systemctl --user stop rclone-gdrive

    Si queremos desactivarlo para que no arranque automáticamente:

    systemctl --user disable rclone-gdrive

    14. Posibles errores y soluciones

    Error: la carpeta parece vacía

    Primero comprueba si el montaje está activo:

    systemctl --user status rclone-gdrive

    O prueba a montar manualmente:

    rclone mount gdrive: ~/GoogleDrive --vfs-cache-mode writes --daemon

    Error: transport endpoint is not connected

    A veces puede quedarse un montaje bloqueado.

    Solución:

    fusermount3 -u ~/GoogleDrive

    Si no funciona:

    fusermount3 -uz ~/GoogleDrive

    Después vuelve a montar:

    rclone mount gdrive: ~/GoogleDrive --vfs-cache-mode writes --daemon

    Error: command not found

    Si aparece:

    rclone: command not found

    Significa que rclone no está instalado.

    Instálalo con:

    sudo apt install rclone

    Error: fusermount3 no encontrado

    Instala fuse3:

    sudo apt install fuse3

    Error en el servicio por el nombre de usuario

    Si el servicio no arranca, revisa esta parte:

    ExecStart=/usr/bin/rclone mount gdrive: /home/antonio/GoogleDrive --vfs-cache-mode writes
    ExecStop=/bin/fusermount3 -u /home/antonio/GoogleDrive

    Debes cambiar antonio por tu usuario real.

    Puedes saber tu usuario con:

    whoami

    Y tu ruta personal con:

    echo $HOME

    15. Comandos principales de la práctica

    AcciónComando
    Instalar rclonesudo apt install rclone fuse3
    Configurar Google Driverclone config
    Ver carpetas de Driverclone lsd gdrive:
    Crear carpeta de montajemkdir -p ~/GoogleDrive
    Montar Driverclone mount gdrive: ~/GoogleDrive --vfs-cache-mode writes --daemon
    Desmontar Drivefusermount3 -u ~/GoogleDrive
    Ver estado del serviciosystemctl --user status rclone-gdrive
    Iniciar serviciosystemctl --user start rclone-gdrive
    Parar serviciosystemctl --user stop rclone-gdrive

    16. Ejercicio propuesto para el alumno

    Realiza los siguientes pasos y documenta el proceso:

    1. Instala rclone en Ubuntu.
    2. Configura tu cuenta de Google Drive.
    3. Crea la carpeta ~/GoogleDrive.
    4. Monta Google Drive usando rclone mount.
    5. Comprueba que puedes ver tus archivos desde el explorador.
    6. Crea una carpeta de prueba dentro de ~/GoogleDrive.
    7. Comprueba desde la web de Google Drive que la carpeta se ha creado.
    8. Desmonta Google Drive.
    9. Vuelve a montarlo manualmente.
    10. Configura el montaje automático con systemd.

    17. Preguntas de repaso

    1. ¿Qué diferencia hay entre sincronizar Google Drive y montarlo como unidad?
    2. ¿Para qué sirve rclone?
    3. ¿Qué significa gdrive: en los comandos usados?
    4. ¿Dónde se monta Google Drive en esta práctica?
    5. ¿Qué comando se usa para desmontar la unidad?
    6. ¿Qué ventaja tiene usar systemd en esta práctica?
    7. ¿Se descargan todos los archivos de Google Drive al montar la unidad?
    8. ¿Qué ocurre si copiamos un archivo dentro de ~/GoogleDrive?

    18. Conclusión

    En esta práctica hemos montado Google Drive en Ubuntu como una carpeta local usando rclone.

    La ventaja principal de este método es que podemos trabajar con nuestros archivos de Google Drive desde Ubuntu sin tener que sincronizar todo el contenido en el disco duro.

    Esto resulta muy útil en equipos con poco almacenamiento, máquinas virtuales, portátiles o entornos de laboratorio donde necesitamos acceso a archivos en la nube sin ocupar espacio innecesario.

    Además, al configurar el montaje automático mediante systemd, conseguimos que Google Drive esté disponible cada vez que iniciemos sesión en Ubuntu.

  • Instalación de Ollama en Windows paso a paso

    Instalación de Ollama en Windows paso a paso

    1. Introducción

    En esta práctica vamos a instalar Ollama en un equipo con Windows para poder ejecutar modelos de inteligencia artificial de forma local.

    Ollama permite descargar y ejecutar modelos como Llama, Qwen, Mistral u otros modelos compatibles directamente en nuestro ordenador, sin depender necesariamente de servicios externos.

    Esto es especialmente interesante en clase porque nos permite trabajar conceptos como:

    • Inteligencia artificial local.
    • Modelos de lenguaje.
    • Uso de la terminal.
    • Consumo de CPU, RAM y GPU.
    • Servicios accesibles desde red local.
    • Integración con herramientas como Open WebUI, OpenCode o aplicaciones propias.

    2. Requisitos previos

    Para realizar esta práctica necesitaremos:

    • Un equipo con Windows 10 o Windows 11.
    • Conexión a Internet.
    • Permisos para instalar programas.
    • PowerShell o Terminal de Windows.
    • Espacio suficiente en disco para descargar modelos.

    Según la página oficial de Ollama, la versión para Windows requiere Windows 10 o posterior.


    3. ¿Qué vamos a instalar?

    Vamos a instalar:

    Ollama para Windows

    Una vez instalado, podremos ejecutar comandos como:

    ollama --version
    ollama pull llama3.1:8b
    ollama run llama3.1:8b

    Paso 1. Descargar Ollama para Windows

    Entramos en la página oficial de descarga de Ollama:

    https://ollama.com/download/windows

    En la página oficial aparece la opción de descarga para Windows y también una instalación mediante PowerShell.

    Podemos instalarlo de dos formas:

    Opción A: Instalación con instalador gráfico

    Esta es la opción más sencilla para alumnos que empiezan.

    1. Entramos en la web oficial de Ollama.
    2. Seleccionamos la versión de Windows.
    3. Descargamos el instalador.
    4. Ejecutamos el archivo descargado.
    5. Seguimos el asistente de instalación.

    Cuando termine, Ollama debería quedar instalado en el sistema.


    Opción B: Instalación desde PowerShell

    También podemos instalar Ollama usando PowerShell.

    Abrimos PowerShell y ejecutamos:

    irm https://ollama.com/install.ps1 | iex

    Este comando aparece actualmente en la página oficial de descarga de Ollama para Windows.


    Paso 2. Comprobar que Ollama está instalado

    Abrimos una terminal de PowerShell y ejecutamos:

    ollama --version

    Si todo está correcto, veremos una salida parecida a esta:

    ollama version x.x.x

    La versión puede cambiar según el momento en el que se instale.


    Paso 3. Comprobar que el servicio responde

    Ollama funciona como una aplicación/servicio local que escucha normalmente en el puerto:

    11434

    Podemos comprobarlo con:

    curl http://localhost:11434/api/tags

    Si todavía no tenemos modelos instalados, puede aparecer una lista vacía o una respuesta JSON sin modelos.

    Ejemplo aproximado:

    {
    "models": []
    }

    Paso 4. Descargar un primer modelo

    Ahora vamos a descargar un modelo pequeño o mediano para probar.

    Para empezar podemos usar:

    ollama pull llama3.1:8b

    También podríamos usar un modelo orientado a programación, por ejemplo:

    ollama pull qwen2.5-coder:7b

    La descarga puede tardar varios minutos, dependiendo de la conexión a Internet y del tamaño del modelo.


    Paso 5. Ejecutar un modelo

    Una vez descargado el modelo, podemos ejecutarlo con:

    ollama run llama3.1:8b

    Aparecerá un prompt interactivo donde podremos escribir preguntas.

    Por ejemplo:

    >>> Explícame qué es una dirección IP como si fuera para un alumno de primero de ASIR.

    Ollama responderá usando el modelo cargado en local.

    Para salir del chat podemos escribir:

    /bye

    Paso 6. Ver los modelos instalados

    Para ver qué modelos tenemos descargados:

    ollama list

    La salida será parecida a:

    NAME              ID              SIZE      MODIFIED
    llama3.1:8b xxxxxxxx 4.7 GB ...
    qwen2.5-coder:7b xxxxxxxx 4.7 GB ...

    Paso 7. Ver qué modelos están cargados en memoria

    Este paso es importante, especialmente si el ordenador también se usa para jugar, editar vídeo o realizar tareas pesadas.

    Ejecutamos:

    ollama ps

    Este comando muestra los modelos que están cargados en ese momento.

    Ejemplo:

    NAME              ID              SIZE      PROCESSOR    UNTIL
    llama3.1:8b xxxxxxxx 4.7 GB 100% GPU 4 minutes from now

    Paso 8. Detener un modelo cargado

    Si queremos liberar memoria, podemos detener un modelo con:

    ollama stop llama3.1:8b

    O, si estamos usando otro modelo:

    ollama stop qwen2.5-coder:7b

    Esto es útil para liberar RAM o VRAM de la tarjeta gráfica.


    Paso 9. Borrar un modelo

    Si queremos eliminar un modelo descargado para liberar espacio en disco:

    ollama rm llama3.1:8b

    Después podemos comprobar de nuevo:

    ollama list

    Paso 10. Probar Ollama desde el navegador

    Podemos abrir en el navegador:

    http://localhost:11434

    También podemos probar directamente la API:

    http://localhost:11434/api/tags

    El endpoint /api/tags permite comprobar los modelos disponibles en la instalación local.


    Paso 11. Crear una petición a la API de Ollama

    Ollama no solo sirve para usar modelos desde terminal. También podemos hacer peticiones HTTP a su API local.

    Ejemplo desde PowerShell:

    curl http://localhost:11434/api/generate `
    -Method POST `
    -Body '{"model":"llama3.1:8b","prompt":"Explica qué es Linux en pocas palabras.","stream":false}' `
    -ContentType "application/json"

    Esto nos devolverá una respuesta en formato JSON.


    Paso 12. Configurar Ollama para acceder desde otro equipo de la red

    Por defecto, Ollama suele estar pensado para usarse desde el propio equipo. Si queremos acceder desde otro ordenador de la red local, por ejemplo desde un portátil, podemos configurar la variable de entorno:

    OLLAMA_HOST

    La documentación oficial de Ollama indica que en Windows las variables de entorno se pueden configurar desde las opciones de entorno del usuario o del sistema. Para ello recomienda cerrar primero Ollama desde la barra de tareas, abrir la configuración de variables de entorno, crear o editar la variable correspondiente y volver a iniciar Ollama.

    Configuración recomendada para red local

    Creamos la variable:

    OLLAMA_HOST

    Con el valor:

    0.0.0.0:11434

    También se puede hacer desde PowerShell como administrador:

    setx OLLAMA_HOST "0.0.0.0:11434" /M

    Después debemos cerrar Ollama y volver a abrirlo, o reiniciar el equipo.


    Paso 13. Abrir el puerto en el firewall de Windows

    Si queremos acceder a Ollama desde otro ordenador de la misma red, puede ser necesario abrir el puerto 11434.

    Abrimos PowerShell como administrador y ejecutamos:

    New-NetFirewallRule `
    -DisplayName "Ollama 11434" `
    -Direction Inbound `
    -Protocol TCP `
    -LocalPort 11434 `
    -Action Allow

    Paso 14. Averiguar la IP del equipo Windows

    En el equipo donde está instalado Ollama ejecutamos:

    ipconfig

    Buscamos la dirección IPv4 de la tarjeta de red que estamos usando.

    Ejemplo:

    Dirección IPv4. . . . . . . . . . . . . . : 192.168.1.50

    En este ejemplo, la IP del equipo sería:

    192.168.1.50

    Paso 15. Probar Ollama desde otro ordenador

    Desde otro equipo de la misma red, por ejemplo un portátil, probamos:

    curl http://192.168.1.50:11434/api/tags

    Cambiando 192.168.1.50 por la IP real del equipo Windows.

    Si todo está correcto, veremos la lista de modelos disponibles.


    Paso 16. Conectar Open WebUI u otra herramienta

    Si instalamos una interfaz web como Open WebUI, podremos conectarla a la dirección del servidor Ollama.

    Si Open WebUI está en el mismo equipo:

    http://localhost:11434

    Si Open WebUI está en otro ordenador de la red:

    http://192.168.1.50:11434

    Paso 17. Recomendaciones de modelos para empezar

    Para equipos normales:

    ollama pull llama3.1:8b
    ollama pull qwen2.5-coder:7b

    Para equipos con buena GPU:

    ollama pull qwen2.5-coder:14b
    ollama pull qwen3:14b

    Para programación:

    ollama run qwen2.5-coder:7b

    O, si el equipo tiene más potencia:

    ollama run qwen2.5-coder:14b

    Para uso general:

    ollama run llama3.1:8b

    Paso 18. Buenas prácticas si el equipo también se usa para jugar

    Si el ordenador tiene una tarjeta gráfica potente y también se usa para jugar, conviene tener cuidado.

    Ollama puede usar:

    • RAM.
    • CPU.
    • GPU.
    • VRAM de la tarjeta gráfica.
    • Disco.

    Instalar Ollama no debería reducir el rendimiento de los juegos por sí solo. El problema aparece cuando tenemos un modelo cargado mientras jugamos.

    Antes de jugar podemos comprobar:

    ollama ps

    Si aparece algún modelo cargado, podemos detenerlo:

    ollama stop nombre_del_modelo

    Por ejemplo:

    ollama stop qwen2.5-coder:14b

    También podemos cerrar Ollama desde el icono de la bandeja del sistema.


    Paso 19. Seguridad básica

    No debemos exponer Ollama directamente a Internet.

    Una cosa es usarlo dentro de nuestra red local y otra muy distinta dejarlo accesible públicamente desde fuera.

    Recomendaciones:

    • No abrir el puerto 11434 en el router.
    • No hacer redirección de puertos hacia Ollama.
    • Usarlo solo en red local.
    • Si se necesita acceso remoto, usar VPN o una solución segura.
    • No permitir que cualquier persona de la red use modelos grandes sin control.

    Paso 20. Comandos principales de Ollama

    AcciónComando
    Ver versiónollama --version
    Descargar modeloollama pull nombre_modelo
    Ejecutar modeloollama run nombre_modelo
    Ver modelos instaladosollama list
    Ver modelos cargadosollama ps
    Detener modeloollama stop nombre_modelo
    Borrar modeloollama rm nombre_modelo
    Probar API localcurl http://localhost:11434/api/tags

    Actividad propuesta

    Instalar Ollama en Windows, descargar un modelo, ejecutarlo y comprobar que funciona correctamente desde terminal y desde la API local.

    Tareas

    1. Instalar Ollama en Windows.
    2. Comprobar la versión instalada.
    3. Descargar un modelo.
    4. Ejecutar el modelo desde terminal.
    5. Hacerle al modelo una pregunta técnica.
    6. Listar los modelos instalados.
    7. Comprobar qué modelos están cargados.
    8. Probar la API local con curl.
    9. Documentar el proceso con capturas.
    10. Explicar qué recursos del equipo consume Ollama.

    Cargar modelos de ollama en el disco duro secundario

    Importante:
    Los modelos de Ollama pueden ocupar muchos gigabytes. En equipos con un disco principal pequeño, es recomendable guardar los modelos en un disco secundario usando la variable de entorno OLLAMA_MODELS. Así evitamos llenar la unidad C: y mantenemos el sistema operativo con espacio libre suficiente.

    la forma correcta para Windows, que es mover la carpeta de modelos usando la variable OLLAMA_MODELS. También voy a incluir una alternativa con enlace simbólico, útil si ya tienes modelos descargados.Pensó durante 4s

    Sí. En Windows tienes que cambiar la ubicación de los modelos con la variable de entorno OLLAMA_MODELS. Ollama indica oficialmente que esta variable sirve para elegir dónde se guardan los modelos descargados.

    Por ejemplo, si quieres que los modelos estén en el disco D:, puedes crear esta carpeta:

    D:\Ollama\Models

    Opción recomendada: usar OLLAMA_MODELS

    1. Crea la carpeta en el disco secundario

    En PowerShell:

    mkdir D:\Ollama\Models

    Puedes cambiar D: por la letra real de tu disco.


    2. Cierra Ollama

    Antes de cambiar la ruta:

    1. Ve al icono de Ollama en la bandeja del sistema, junto al reloj.
    2. Clic derecho.
    3. Pulsa Quit o Salir.

    También puedes cerrar el proceso desde PowerShell:

    taskkill /IM ollama.exe /F

    3. Crea la variable de entorno

    Abre PowerShell como administrador y ejecuta:

    setx OLLAMA_MODELS "D:\Ollama\Models" /M

    Esto crea la variable a nivel de sistema.

    También podrías crearla solo para tu usuario:

    setx OLLAMA_MODELS "D:\Ollama\Models"

    Para un PC personal, yo usaría la opción con /M.


    4. Reinicia Ollama

    Después de crear la variable:

    • Cierra todas las terminales.
    • Vuelve a abrir PowerShell.
    • Abre Ollama de nuevo desde el menú de inicio.

    Para ir a lo seguro, reinicia Windows.


    5. Comprueba que la variable existe

    En una nueva ventana de PowerShell:

    echo $env:OLLAMA_MODELS

    Debería aparecer:

    D:\Ollama\Models

    6. Descarga un modelo de prueba

    Por ejemplo:

    ollama pull llama3.1:8b

    Después comprueba que se han creado archivos dentro de:

    D:\Ollama\Models

    Si ya tenías modelos descargados

    Por defecto, Ollama suele guardar los modelos en la carpeta del usuario, dentro de:

    C:\Users\TU_USUARIO\.ollama

    La documentación oficial también indica que %HOMEPATH%\.ollama contiene modelos y configuración.

    Puedes moverlos así:

    1. Cierra Ollama

    taskkill /IM ollama.exe /F

    2. Copia la carpeta antigua al nuevo disco

    Por ejemplo:

    robocopy "$env:USERPROFILE\.ollama\models" "D:\Ollama\Models" /E

    3. Crea la variable OLLAMA_MODELS

    setx OLLAMA_MODELS "D:\Ollama\Models" /M

    4. Reinicia Windows

    Después prueba:

    ollama list

    Si los modelos aparecen correctamente, ya está usando la nueva ubicación.


  • Instalación y uso de OpenCode en Windows con WSL Ubuntu

    Instalación y uso de OpenCode en Windows con WSL Ubuntu

    1. Introducción

    OpenCode es una herramienta de asistencia al desarrollo mediante inteligencia artificial. Permite trabajar con proyectos de programación desde la terminal, hacer preguntas sobre el código, pedir cambios, generar archivos, revisar errores y trabajar con diferentes proveedores de modelos de IA.

    Aunque OpenCode puede instalarse de varias formas, en Windows la opción más recomendable para trabajar de manera seria es usarlo dentro de WSL, es decir, el Subsistema de Windows para Linux. De esta forma trabajaremos con un entorno Linux real dentro de Windows, algo muy útil para programación, servidores, automatización y administración de sistemas.

    OpenCode está disponible como herramienta de terminal, aplicación de escritorio e incluso extensiones para editores como Visual Studio Code. La versión de escritorio está disponible en beta para Windows x64.


    Objetivos de la práctica

    Al finalizar esta práctica, el alumno será capaz de:

    • Instalar WSL en Windows.
    • Instalar Ubuntu dentro de WSL.
    • Instalar OpenCode en el entorno Linux.
    • Abrir un proyecto con Visual Studio Code usando Remote WSL.
    • Ejecutar OpenCode desde la terminal del proyecto.
    • Conectar OpenCode con un proveedor de IA.
    • Comprender la diferencia entre usar OpenCode en terminal, escritorio o navegador.

    Requisitos previos

    Para realizar esta práctica necesitaremos:

    • Un equipo con Windows 10 o Windows 11.
    • Conexión a Internet.
    • Permisos de administrador en Windows.
    • Visual Studio Code instalado.
    • Una cuenta o clave de acceso para algún proveedor de IA compatible, por ejemplo OpenAI, GitHub Copilot, OpenRouter, Anthropic, Google Gemini u otro proveedor compatible.

    OpenCode necesita un proveedor de modelos de lenguaje para funcionar. La herramienta puede ser gratuita, pero el uso del modelo puede depender del proveedor elegido.


    Paso 1. Instalar WSL en Windows

    Abrimos PowerShell como administrador.

    Para ello:

    1. Pulsamos en el menú de inicio.
    2. Escribimos PowerShell.
    3. Hacemos clic derecho.
    4. Seleccionamos Ejecutar como administrador.

    Después ejecutamos:

    wsl --install

    Este comando instalará WSL y, normalmente, también una distribución Ubuntu por defecto.

    Cuando finalice la instalación, reiniciamos el equipo si Windows lo solicita.


    Paso 2. Comprobar que WSL funciona

    Después del reinicio, abrimos una terminal de Ubuntu desde el menú de inicio.

    Buscamos:

    Ubuntu

    Si no lo vemos, probamos lo siguiente:

    Ejecuta:

    wsl --list --online

    Esto te mostrará las distribuciones disponibles.


    Instala Ubuntu manualmente

    Ejecuta:

    wsl --install -d Ubuntu

    Reinicia el ordenador si te lo pide.

    Si al reinicar aun no aparece, vuelve a poner

    wsl --install -d Ubuntu

    Comprueba qué distribuciones tienes instaladas

    Después abre PowerShell normal y ejecuta:

    wsl -l -v

    Deberías ver algo parecido a:

      NAME      STATE           VERSION
    * Ubuntu Stopped 2

    Si aparece Ubuntu, puedes abrirlo con:

    wsl

    o también:

    ubuntu

    La primera vez que se abra, Ubuntu nos pedirá crear un usuario y una contraseña.

    Por ejemplo:

    Enter new UNIX username: alumno
    New password:
    Retype new password:

    La contraseña no se verá mientras la escribimos. Esto es normal en Linux.


    Paso 3. Actualizar Ubuntu

    Dentro de la terminal de Ubuntu ejecutamos:

    sudo apt update
    sudo apt upgrade -y

    Con esto actualizamos la lista de paquetes y los programas instalados.

    Es importante hacer este paso antes de instalar herramientas de desarrollo.


    Paso 4. Instalar herramientas básicas

    Instalamos algunas herramientas útiles:

    sudo apt install -y curl git unzip

    Estas herramientas nos permitirán descargar archivos, trabajar con repositorios y preparar proyectos.


    Paso 5. Instalar OpenCode dentro de WSL

    La documentación oficial de OpenCode recomienda instalarlo en WSL para trabajar desde Windows. Una vez dentro de la terminal de Ubuntu, ejecutamos el instalador oficial:

    curl -fsSL https://opencode.ai/install | bash

    Cuando termine la instalación, cerramos y volvemos a abrir la terminal de Ubuntu.

    Después comprobamos que OpenCode está instalado:

    opencode --version

    Si aparece una versión, la instalación ha funcionado correctamente.


    Paso 6. Crear una carpeta de trabajo

    Vamos a crear una carpeta para nuestros proyectos dentro del entorno Linux.

    mkdir -p ~/proyectos
    cd ~/proyectos

    Ahora podemos crear un proyecto de prueba:

    mkdir prueba-opencode
    cd prueba-opencode

    Creamos un archivo simple:

    nano index.html

    Pegamos este contenido:

    <!DOCTYPE html>
    <html lang="es">
    <head>
    <meta charset="UTF-8">
    <title>Prueba OpenCode</title>
    </head>
    <body>
    <h1>Hola desde OpenCode</h1>
    <p>Este es mi primer proyecto usando OpenCode en WSL.</p>
    </body>
    </html>

    Guardamos con:

    CTRL + O
    Enter
    CTRL + X

    Paso 7. Ejecutar OpenCode en el proyecto

    Desde la carpeta del proyecto ejecutamos:

    opencode

    OpenCode se iniciará en la terminal.

    La primera vez puede solicitar configuración o conexión con un proveedor de IA.

    Dentro de OpenCode podemos usar comandos como:

    /connect

    Este comando permite conectar OpenCode con un proveedor de modelos de IA.

    Dependiendo del proveedor elegido, puede pedir una clave API, iniciar sesión o configurar una cuenta.


    Paso 8. Primeras pruebas con OpenCode

    Una vez abierto OpenCode dentro del proyecto, podemos pedirle tareas sencillas.

    Por ejemplo:

    Explícame qué hace este proyecto.

    También podemos pedirle mejoras:

    Mejora el archivo index.html añadiendo una estructura básica con cabecera, contenido principal y pie de página.

    O podemos pedirle que cree nuevos archivos:

    Crea un archivo styles.css y enlázalo desde index.html.

    OpenCode puede ayudar a escribir, modificar y revisar código, pero el alumno siempre debe revisar los cambios antes de aceptarlos. La IA puede equivocarse, generar código innecesario o modificar partes que no debería.


    Paso 9. Instalar Visual Studio Code

    Si no lo tenemos instalado, descargamos e instalamos Visual Studio Code desde su página oficial.

    Una vez instalado, abrimos Visual Studio Code.


    Paso 10. Instalar la extensión Remote WSL

    En Visual Studio Code:

    1. Vamos a la sección Extensions.
    2. Buscamos:
    WSL
    1. Instalamos la extensión oficial de Microsoft llamada WSL.

    Esta extensión permite abrir carpetas de Linux/WSL directamente desde Visual Studio Code.


    Paso 11. Abrir el proyecto desde WSL en Visual Studio Code

    Volvemos a la terminal de Ubuntu y nos situamos en nuestro proyecto:

    cd ~/proyectos/prueba-opencode

    Ejecutamos:

    code .

    La primera vez puede tardar un poco, porque Visual Studio Code instalará algunos componentes dentro de WSL.

    Cuando se abra Visual Studio Code, veremos que estamos trabajando dentro del entorno WSL.

    Esto es importante: aunque estamos usando una aplicación gráfica de Windows, el proyecto realmente está dentro de Ubuntu.


    Paso 12. Abrir una terminal integrada en Visual Studio Code

    Dentro de Visual Studio Code:

    1. Vamos al menú Terminal.
    2. Pulsamos New Terminal.
    3. Comprobamos que la terminal abierta es de Ubuntu/WSL.

    Podemos probarlo ejecutando:

    pwd

    Debería aparecer una ruta parecida a:

    /home/alumno/proyectos/prueba-opencode

    Ahora podemos lanzar OpenCode directamente desde la terminal integrada:

    opencode

    Esta forma de trabajar es muy cómoda porque tenemos:

    • El editor Visual Studio Code.
    • El proyecto abierto.
    • La terminal Linux.
    • OpenCode trabajando sobre la carpeta real del proyecto.

    Paso 13. Acceder a proyectos de Windows desde WSL

    Aunque es recomendable guardar los proyectos dentro de Linux, también podemos acceder a carpetas de Windows desde WSL.

    Por ejemplo, el disco C: de Windows aparece en WSL como:

    /mnt/c/

    Ejemplo:

    cd /mnt/c/Users/TuUsuario/Desktop

    El disco D: aparecería como:

    /mnt/d/

    Y así sucesivamente.

    La documentación oficial de OpenCode indica que desde WSL podemos navegar a proyectos de Windows usando rutas como /mnt/c/Users/YourName/project y ejecutar allí opencode.

    Aun así, para proyectos de programación es mejor trabajar dentro de:

    /home/usuario/proyectos

    Suele dar menos problemas de permisos, rendimiento y compatibilidad.


    Paso 14. Usar la versión web de OpenCode desde WSL

    OpenCode también puede ejecutarse como interfaz web en el navegador. La documentación oficial recomienda que, en Windows, se ejecute desde WSL para mantener buen acceso al sistema de archivos y a la terminal.

    Desde la carpeta del proyecto podemos ejecutar:

    opencode web --hostname 0.0.0.0

    OpenCode mostrará una dirección local en la terminal.

    Después podremos abrirla desde el navegador de Windows.

    Normalmente será algo parecido a:

    http://localhost:PUERTO

    donde PUERTO será el número que indique OpenCode.


    Paso 15. Usar la aplicación de escritorio de OpenCode

    OpenCode también tiene una aplicación de escritorio en beta para Windows x64.

    La idea sería:

    1. Instalar OpenCode Desktop para Windows.
    2. Ejecutar el servidor de OpenCode dentro de WSL.
    3. Conectar la aplicación de escritorio al servidor local.

    Desde WSL podemos lanzar el servidor con:

    opencode serve --hostname 0.0.0.0 --port 4096

    Después, desde la aplicación de escritorio, nos conectaríamos a:

    http://localhost:4096

    Si localhost no funciona, podemos obtener la IP de WSL con:

    hostname -I

    Y conectarnos usando una dirección parecida a:

    http://IP-DE-WSL:4096

    La documentación oficial advierte que, si usamos --hostname 0.0.0.0, conviene proteger el servidor con contraseña mediante la variable OPENCODE_SERVER_PASSWORD.

    Ejemplo:

    OPENCODE_SERVER_PASSWORD=clave-segura opencode serve --hostname 0.0.0.0 --port 4096

    Paso 16. Recomendación para clase

    Para esta práctica vamos a trabajar principalmente de esta forma:

    Windows + WSL Ubuntu + Visual Studio Code + OpenCode en terminal

    Es decir:

    1. Usamos Windows como sistema principal.
    2. Usamos Ubuntu mediante WSL como entorno de desarrollo.
    3. Abrimos los proyectos con Visual Studio Code usando Remote WSL.
    4. Ejecutamos OpenCode desde la terminal del proyecto.

    Esta forma de trabajo es muy parecida a un entorno profesional real, porque muchos servidores, herramientas de desarrollo y sistemas de despliegue funcionan sobre Linux.


    Paso 17. Comandos resumen

    Instalar WSL

    wsl --install

    Actualizar Ubuntu

    sudo apt update
    sudo apt upgrade -y

    Instalar herramientas básicas

    sudo apt install -y curl git unzip

    Instalar OpenCode

    curl -fsSL https://opencode.ai/install | bash

    Comprobar versión

    opencode --version

    Crear proyecto

    mkdir -p ~/proyectos/prueba-opencode
    cd ~/proyectos/prueba-opencode

    Abrir Visual Studio Code desde WSL

    code .

    Ejecutar OpenCode

    opencode

    Ejecutar OpenCode Web

    opencode web --hostname 0.0.0.0

    Ejecutar servidor para escritorio

    opencode serve --hostname 0.0.0.0 --port 4096

    Problemas frecuentes

    El comando opencode no se reconoce

    Cerramos y volvemos a abrir la terminal de Ubuntu.

    También podemos probar:

    source ~/.bashrc

    Después:

    opencode --version

    El comando code . no funciona

    Puede deberse a que Visual Studio Code no está instalado correctamente o no está disponible en el PATH.

    Solución:

    1. Abrir Visual Studio Code en Windows.
    2. Instalar la extensión WSL.
    3. Volver a abrir Ubuntu.
    4. Probar de nuevo:
    code .

    OpenCode no puede conectarse al proveedor de IA

    Revisamos:

    • Que tenemos conexión a Internet.
    • Que la clave API es correcta.
    • Que hemos usado el comando /connect.
    • Que el proveedor elegido está disponible.
    • Que la cuenta tiene saldo, suscripción o permisos suficientes.

    Estoy en PowerShell y no en Ubuntu

    OpenCode para esta práctica debe ejecutarse dentro de Ubuntu/WSL.

    Si estamos en PowerShell, veremos algo parecido a:

    PS C:\Users\Alumno>

    Si estamos en Ubuntu/WSL, veremos algo parecido a:

    alumno@equipo:~$

    Para entrar en Ubuntu, abrimos la aplicación Ubuntu desde el menú de inicio.


    Actividad propuesta para el alumno

    Crea un pequeño proyecto web con estos archivos:

    index.html
    styles.css
    script.js

    El proyecto debe tener:

    • Una página principal con título.
    • Un párrafo explicando qué es OpenCode.
    • Un botón creado con HTML.
    • Estilos básicos en CSS.
    • Un pequeño mensaje en JavaScript al pulsar el botón.

    Después abre OpenCode desde la carpeta del proyecto y pídele:

    Revisa este proyecto y propón mejoras sencillas para un alumno que está empezando.

    A continuación, el alumno deberá entregar:

    • Captura de WSL funcionando.
    • Captura de opencode --version.
    • Captura de Visual Studio Code abierto con Remote WSL.
    • Captura de OpenCode ejecutándose en la terminal del proyecto.
    • Breve explicación de qué ventajas tiene trabajar con WSL en Windows.

    Conclusión

    OpenCode puede utilizarse directamente en Windows, pero para un entorno de clase y de desarrollo técnico es más recomendable utilizarlo dentro de WSL con Ubuntu.

    De esta manera conseguimos un entorno más parecido al que encontraremos en servidores reales, con mejor integración con herramientas Linux y con una forma de trabajo muy útil para programación, administración de sistemas, ciberseguridad y automatización.

    La combinación recomendada para el curso será:

    Windows + WSL Ubuntu + Visual Studio Code Remote WSL + OpenCode
  • Práctica guiada: Instalación de Cypht en Ubuntu Server con Docker

    Práctica guiada: Instalación de Cypht en Ubuntu Server con Docker

    1. Introducción

    En esta práctica vamos a instalar Cypht en una máquina Ubuntu Server.

    Cypht es una aplicación web que permite consultar varias cuentas de correo desde una única interfaz. A diferencia de otros clientes webmail más clásicos, Cypht está pensado para actuar como un agregador de cuentas de correo, por lo que resulta especialmente útil cuando queremos gestionar varias direcciones desde el navegador.

    Durante la práctica utilizaremos Docker y Docker Compose, ya que esto nos permite instalar Cypht junto con su base de datos de una forma más limpia, controlada y fácil de mantener.


    2. Objetivos de la práctica

    Al finalizar esta práctica, el alumno será capaz de:

    • Crear una máquina virtual Ubuntu Server.
    • Instalar Docker en Ubuntu Server.
    • Usar Docker Compose para desplegar varios servicios.
    • Instalar Cypht junto con MariaDB.
    • Acceder a Cypht desde un navegador web.
    • Comprender el funcionamiento básico de un servicio web desplegado con contenedores.
    • Solucionar errores habituales relacionados con permisos de Docker.

    3. Escenario de la práctica

    Vamos a crear el siguiente entorno:

    Navegador del alumno
    |
    v
    http://IP_DEL_SERVIDOR:8085
    |
    v
    Ubuntu Server
    |
    +-- Contenedor Cypht
    |
    +-- Contenedor MariaDB

    Cypht será la aplicación web y MariaDB almacenará la configuración y los datos necesarios.


    4. Requisitos previos

    Para realizar esta práctica necesitamos:

    • Una máquina virtual con Ubuntu Server 24.04 o similar.
    • Acceso a Internet desde la máquina virtual.
    • Un usuario con permisos de sudo.
    • Al menos:
      • 2 CPU
      • 4 GB de RAM recomendados
      • 25 GB de disco como mínimo
    • Conocimientos básicos de terminal Linux.

    5. Configuración recomendada de la máquina virtual

    Si se trabaja con Proxmox, VirtualBox, VMware o similar, se recomienda crear la máquina con estos valores:

    RecursoValor recomendado
    Sistema operativoUbuntu Server 24.04
    CPU2 cores
    RAM4 GB
    Disco25 GB mínimo
    RedNAT o adaptador puente
    AccesoConsola o SSH

    Importante:
    Con 1 CPU y 2 GB de RAM la instalación puede funcionar, pero el sistema irá justo. Para trabajar cómodamente con Docker, Cypht y MariaDB, se recomienda usar 2 CPU y 4 GB de RAM.


    Parte 1: Preparación del sistema

    Paso 1. Actualizar el sistema

    sudo apt update

    Entramos en la máquina Ubuntu Server y actualizamos los repositorios:

    Después actualizamos los paquetes instalados:

    sudo apt upgrade -y

    Paso 2. Instalar herramientas necesarias

    Instalamos algunos paquetes que necesitaremos para añadir el repositorio oficial de Docker:

    sudo apt install -y ca-certificates curl gnupg

    Parte 2: Instalación de Docker

    Paso 3. Crear el directorio para las claves de Docker

    Ejecutamos:

    sudo install -m 0755 -d /etc/apt/keyrings

    Este directorio se usará para guardar la clave GPG del repositorio oficial de Docker.


    Paso 4. Descargar la clave GPG de Docker

    Ejecutamos:

    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
    sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

    Después damos permisos de lectura a la clave:

    sudo chmod a+r /etc/apt/keyrings/docker.gpg

    Paso 5. Añadir el repositorio oficial de Docker

    Ejecutamos el siguiente comando completo:

    echo \
    "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
    https://download.docker.com/linux/ubuntu \
    $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
    sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

    Actualizamos de nuevo los repositorios:

    sudo apt update

    Paso 6. Instalar Docker y Docker Compose

    Instalamos Docker:

    sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

    Comprobamos que Docker se ha instalado correctamente:

    docker --version

    Y comprobamos Docker Compose:

    docker compose version

    Si los comandos muestran una versión, la instalación ha sido correcta.


    Paso 7. Comprobar el estado del servicio Docker

    Ejecutamos:

    sudo systemctl status docker

    Si aparece como active (running), Docker está funcionando.

    Podemos salir de esa pantalla pulsando:

    q

    Si Docker no estuviera activo, lo arrancamos con:

    sudo systemctl enable --now docker

    Parte 3: Preparación de Cypht

    Paso 8. Crear la carpeta de trabajo

    Crearemos la instalación en /opt/cypht.

    sudo mkdir -p /opt/cypht

    Cambiamos el propietario de la carpeta para poder trabajar cómodamente con nuestro usuario:

    sudo chown -R $USER:$USER /opt/cypht

    Entramos en la carpeta:

    cd /opt/cypht

    Paso 9. Crear el archivo docker-compose.yml

    Creamos el archivo:

    nano docker-compose.yml

    Dentro pegamos el siguiente contenido:

    services:
    db:
    image: mariadb:10
    container_name: cypht-db
    restart: unless-stopped
    volumes:
    - ./data/mysql:/var/lib/mysql
    environment:
    MYSQL_ROOT_PASSWORD: Cambia_Esta_Clave_Root
    MYSQL_DATABASE: cypht
    MYSQL_USER: cypht
    MYSQL_PASSWORD: Cambia_Esta_Clave_Cypht
    healthcheck:
    test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-ucypht", "-pCambia_Esta_Clave_Cypht"]
    interval: 10s
    timeout: 5s
    retries: 5

    cypht:
    image: cypht/cypht:2.8.0
    container_name: cypht
    restart: unless-stopped
    depends_on:
    db:
    condition: service_healthy
    ports:
    - "8085:80"
    environment:
    AUTH_USERNAME: admin
    AUTH_PASSWORD: Cambia_Esta_Clave_Admin

    DB_CONNECTION_TYPE: host
    DB_DRIVER: mysql
    DB_HOST: db
    DB_NAME: cypht
    DB_USER: cypht
    DB_PASS: Cambia_Esta_Clave_Cypht

    SESSION_TYPE: DB
    USER_CONFIG_TYPE: DB
    volumes:
    - ./data/log/nginx:/var/log/nginx
    - ./data/log/php:/var/log/php
    - ./data/log/supervisord:/var/log/supervisord
    - ./data/fonts:/usr/local/share/cypht/site/fonts

    Guardamos el archivo en nano:

    Ctrl + O
    Enter
    Ctrl + X

    Paso 10. Cambiar las contraseñas

    Antes de arrancar los contenedores, debemos modificar las siguientes claves:

    Cambia_Esta_Clave_Root
    Cambia_Esta_Clave_Cypht
    Cambia_Esta_Clave_Admin

    Podemos editar el archivo de nuevo:

    nano docker-compose.yml

    Por ejemplo:

    MYSQL_ROOT_PASSWORD: Root_1234_segura
    MYSQL_PASSWORD: Cypht_1234_segura
    AUTH_PASSWORD: Admin_1234_segura
    DB_PASS: Cypht_1234_segura

    Importante:
    La contraseña MYSQL_PASSWORD y la contraseña DB_PASS deben coincidir, porque una define la contraseña del usuario de la base de datos y la otra es la contraseña que usará Cypht para conectarse a esa base de datos.


    Parte 4: Arranque de Cypht

    Paso 11. Levantar los contenedores

    Desde la carpeta /opt/cypht, ejecutamos:

    sudo docker compose up -d

    La opción -d significa que los contenedores se ejecutarán en segundo plano.


    Paso 12. Comprobar que los contenedores están funcionando

    Ejecutamos:

    sudo docker ps

    Deberíamos ver dos contenedores:

    • cypht
    • cypht-db

    Ejemplo de salida esperada:

    CONTAINER ID   IMAGE              PORTS                  NAMES
    xxxxxxxxxxxx cypht/cypht:2.8.0 0.0.0.0:8085->80/tcp cypht
    xxxxxxxxxxxx mariadb:10 3306/tcp cypht-db

    Paso 13. Ver los logs si algo falla

    Si algún contenedor no aparece o hay problemas, revisamos los logs:

    sudo docker compose logs -f

    Para salir de los logs:

    Ctrl + C

    También podemos ver solo los logs de Cypht:

    sudo docker compose logs -f cypht

    O solo los de MariaDB:

    sudo docker compose logs -f db

    Parte 5: Acceso desde el navegador

    Paso 14. Obtener la IP del servidor

    Ejecutamos:

    ip a

    Buscamos la dirección IP de la tarjeta de red principal. Suele aparecer en interfaces como:

    ens18
    ens33
    eth0
    enp0s3

    Ejemplo:

    inet 192.168.1.80/24

    En este caso, la IP sería:

    192.168.1.80

    Paso 15. Entrar en Cypht desde el navegador

    Desde el ordenador anfitrión o desde otro equipo de la misma red, abrimos:

    http://IP_DEL_SERVIDOR:8085

    Por ejemplo:

    http://192.168.1.80:8085

    El usuario será:

    admin

    La contraseña será la que hayamos puesto en:

    AUTH_PASSWORD

    Parte 6: Apertura del puerto en el firewall

    Paso 16. Comprobar si UFW está activo

    Ejecutamos:

    sudo ufw status

    Si aparece como inactive, no hace falta abrir nada.

    Si aparece como active, abrimos el puerto 8085:

    sudo ufw allow 8085/tcp

    Comprobamos de nuevo:

    sudo ufw status

    Parte 7: Añadir cuentas de correo en Cypht

    Paso 17. Datos necesarios para configurar una cuenta

    Para añadir una cuenta de correo en Cypht necesitamos conocer los datos del servidor de correo.

    Normalmente necesitaremos:

    DatoEjemplo
    Servidor IMAPmail.midominio.com
    Puerto IMAP993
    Seguridad IMAPSSL/TLS
    Usuariousuario@midominio.com
    ContraseñaContraseña del correo
    Servidor SMTPmail.midominio.com
    Puerto SMTP587
    Seguridad SMTPSTARTTLS

    Paso 18. Añadir una cuenta IMAP

    Dentro de Cypht:

    1. Entramos con el usuario admin.
    2. Accedemos a la configuración.
    3. Buscamos la sección de cuentas o servidores IMAP.
    4. Añadimos los datos de la cuenta.
    5. Guardamos la configuración.

    Ejemplo de configuración IMAP:

    Servidor IMAP: mail.midominio.com
    Puerto: 993
    Seguridad: SSL/TLS
    Usuario: usuario@midominio.com
    Contraseña: ********

    Paso 19. Añadir una cuenta SMTP

    Para poder enviar correos también debemos configurar SMTP.

    Ejemplo:

    Servidor SMTP: mail.midominio.com
    Puerto: 587
    Seguridad: STARTTLS
    Usuario: usuario@midominio.com
    Contraseña: ********

    Nota:
    En algunos proveedores de correo puede ser necesario activar el acceso por aplicaciones externas o generar una contraseña específica de aplicación.


    Parte 8: Comandos básicos de administración

    Ver contenedores activos

    sudo docker ps

    Ver todos los contenedores, incluso los detenidos

    sudo docker ps -a

    Parar Cypht

    cd /opt/cypht
    sudo docker compose down

    Arrancar Cypht de nuevo

    cd /opt/cypht
    sudo docker compose up -d

    Reiniciar los contenedores

    cd /opt/cypht
    sudo docker compose restart

    Ver logs

    cd /opt/cypht
    sudo docker compose logs -f

    Actualizar imágenes

    cd /opt/cypht
    sudo docker compose pull
    sudo docker compose up -d

    Parte 9: Error habitual de permisos con Docker

    Problema

    Puede aparecer este error:

    unable to get image 'mariadb:10': permission denied while trying to connect to the docker API at unix:///var/run/docker.sock

    Este error significa que el usuario actual no tiene permisos para comunicarse con Docker.


    Solución rápida

    Ejecutar el comando con sudo:

    sudo docker compose up -d

    Solución permanente

    Añadimos nuestro usuario al grupo docker:

    sudo usermod -aG docker $USER

    Después reiniciamos la máquina:

    sudo reboot

    Cuando vuelva a arrancar, comprobamos:

    docker ps

    Si ya no aparece el error, podremos usar Docker sin sudo.

    Importante:
    Añadir un usuario al grupo docker le da mucho poder sobre el sistema. En un servidor real, esto debe hacerse solo con usuarios de confianza.


    Parte 10: Comprobaciones finales

    Al terminar la práctica, debemos comprobar:

    ComprobaciónResultado esperado
    Docker está instaladodocker --version muestra una versión
    Docker Compose funcionadocker compose version muestra una versión
    Los contenedores están activossudo docker ps muestra cypht y cypht-db
    Cypht responde en navegadorSe puede acceder a http://IP:8085
    El usuario admin funcionaPodemos iniciar sesión
    El puerto está abiertoEl navegador conecta correctamente
    Se puede añadir una cuenta IMAPLa cuenta aparece en Cypht