Saltar a contenido

Lab 01 — Entorno y primer script PHP

Campo Valor
Módulo Implantación de Aplicaciones Web (IMW)
Ciclo Administración de Sistemas Informáticos en Red (ASIR)
Unidad UT4 — PHP en servidor
Requisitos Ubuntu con acceso sudo
Agrupación Individual
Herramientas Terminal Linux + Apache2 + PHP + navegador + editor de texto
Apuntes ut4_php_01_entorno_php.md
Tiempo estimado 90–120 minutos

Antes de empezar

Qué vamos a hacer

En este primer lab de la UT4 vamos a dejar preparado el entorno de trabajo para todos los labs siguientes:

  • Instalar Apache2 y PHP sobre Ubuntu.
  • Crear la estructura de carpetas del proyecto gestor/ que iremos completando durante toda la unidad.
  • Configurar un VirtualHost de Apache para que nuestro proyecto responda en http://gestor.local.
  • Escribir nuestro primer script PHP.
  • Configurar PHP para ver los errores durante el desarrollo.

Al acabar tendrás una página web generada por PHP funcionando en tu máquina, que será la base de los labs 02 a 11.

Este lab usa dos máquinas: servidor y cliente

Vas a trabajar con dos entornos a la vez:

  • Servidor (VM Ubuntu): donde se instalan Apache y PHP, y donde viven los ficheros .php del proyecto.
  • Cliente (tu Windows): desde donde visitarás las páginas web con el navegador y editarás el hosts.

Cada paso indica en su cabecera dónde se ejecuta. Si no se dice nada, asume que es en el servidor. Ten a mano una terminal SSH al servidor y también PowerShell/CMD de tu Windows.


Cómo se entrega este lab

Al terminar, empaqueta tu trabajo en un ZIP con esta estructura exacta:

apellido_nombre_lab01/
├── gestor/
│   └── public/
│       ├── index.php
│       └── info_servidor.php
├── capturas/
│   ├── paso1_apache_funcionando.png
│   ├── paso2_phpinfo.png
│   ├── paso3_gestor_local.png
│   ├── paso4_pagina_personal.png
│   ├── paso5_error_php.png
│   └── paso6_info_servidor.png
└── RESPUESTAS.md

Nombres prescritos

Los nombres de ficheros y carpetas son obligatorios y exactos. El script de corrección busca estos nombres concretos: si los cambias, tu entrega aparecerá como incompleta.

Cómo preparar la entrega (independientemente del sistema operativo):

  1. Crea una carpeta en tu equipo llamada apellido_nombre_lab01 (en minúsculas, sin espacios ni acentos).
  2. Dentro, reproduce la estructura anterior:
    • gestor/public/index.php y gestor/public/info_servidor.php: los crearás en el servidor durante los pasos siguientes. Cópialos a tu carpeta de entrega antes de hacer el ZIP, usando el método que prefieras.
    • capturas/: los 6 PNG ya renombrados exactamente como se indica.
    • RESPUESTAS.md: fichero Markdown con una sección ## Paso N por pregunta (plantilla al final del documento).
  3. Comprime la carpeta:
    • Windows: clic derecho sobre la carpeta → Enviar aCarpeta comprimida (en zip). El archivo debe llamarse apellido_nombre_lab01.zip.
    • Linux/macOS: zip -r apellido_nombre_lab01.zip apellido_nombre_lab01/.
  4. Abre el ZIP para verificar que al descomprimirlo aparece una sola carpeta raíz llamada apellido_nombre_lab01/.

Comprueba la estructura del ZIP antes de subirlo

Un error habitual en Windows es seleccionar los ficheros dentro de la carpeta en lugar de la carpeta completa y comprimirlos. Eso genera un ZIP sin carpeta raíz que el script de corrección rechaza. Comprime la carpeta apellido_nombre_lab01/, no su contenido.


Paso 1 — Instalar Apache2 y PHP

Conceptos

  • PHP es un lenguaje que se ejecuta en el servidor, no en el navegador (al contrario que HTML/CSS/JavaScript).
  • Apache2 es el servidor web: recibe las peticiones del navegador, ejecuta los ficheros .php a través del módulo de PHP, y devuelve HTML al navegador.
  • El navegador nunca ve código PHP, solo el resultado.
  • Paralelismo con bash: igual que bash script.sh ejecuta un script, Apache + PHP ejecuta tu fichero .php cada vez que alguien visita la URL correspondiente.

Objetivo. Instalar Apache2 y el módulo de PHP en el servidor y verificar que el servicio responde.

Tarea (en el servidor). Desde la terminal de la VM:

# Actualiza la lista de paquetes
sudo apt update

# Instala Apache2 y el módulo de PHP para Apache
sudo apt install -y apache2 php libapache2-mod-php

# Verifica que Apache está en marcha
sudo systemctl status apache2

# Muestra la versión exacta de Apache (la necesitarás para RESPUESTAS.md)
apache2 -v

# Anota la IP del servidor: la vamos a necesitar desde Windows
ip a | grep "inet "

# Verifica que Apache responde — sin navegador, desde el propio servidor
curl -I http://localhost

La salida de systemctl status debe incluir la línea Active: active (running).

La salida de curl -I http://localhost debe empezar por HTTP/1.1 200 OK y mostrar una cabecera Server: Apache/.... Eso confirma que Apache está sirviendo.

Anota la dirección IP del servidor que devuelve ip a (línea del tipo inet 192.168.x.x/24). La usaremos en la siguiente verificación y en todo el lab; la llamaremos IP_DEL_SERVIDOR.

Verificación desde Windows. Ahora abre el navegador de tu Windows y visita http://IP_DEL_SERVIDOR (por ejemplo http://192.168.1.42). Debes ver la página "Apache2 Ubuntu Default Page".

Pista si algo no funciona
  • Si apt install falla por "repositorio no disponible", comprueba tu conexión a internet en la VM.
  • Si systemctl status muestra inactive o failed, prueba sudo systemctl start apache2 y después journalctl -u apache2 -n 20 para ver el error.
  • Si curl -I http://localhost devuelve "Connection refused" desde el servidor, Apache no está arrancado: revisa systemctl status.
  • Si el navegador de Windows no carga http://IP_DEL_SERVIDOR: (a) comprueba conectividad con ping IP_DEL_SERVIDOR desde PowerShell, (b) revisa que la VM está en modo Bridged (no NAT) o que has redirigido el puerto 80.

Responde en RESPUESTAS.md, sección ## Paso 1.

¿Qué versión de Apache2 se ha instalado? Copia la línea "Server version" de la salida de apache2 -v.

Captura requerida. Guarda en capturas/paso1_apache_funcionando.png una captura del navegador de tu Windows visitando http://IP_DEL_SERVIDOR. Debe verse:

  • La URL http://IP_DEL_SERVIDOR (con la IP real) en la barra de direcciones.
  • El título "Apache2 Ubuntu Default Page".

Verificación.

  • sudo systemctl status apache2 muestra Active: active (running).
  • curl -I http://localhost desde el servidor devuelve HTTP/1.1 200 OK.
  • He anotado la IP_DEL_SERVIDOR.
  • El navegador de mi Windows carga http://IP_DEL_SERVIDOR con la página de Apache.
  • He guardado capturas/paso1_apache_funcionando.png.

Paso 2 — Verificar que PHP funciona

Conceptos

  • La función phpinfo() muestra toda la configuración de PHP: versión, módulos cargados, rutas de configuración, etc. Es la forma estándar de comprobar que Apache está ejecutando PHP correctamente.
  • El directorio raíz de Apache es /var/www/html/: los ficheros que estén aquí son accesibles desde el navegador a través de http://localhost/....

Aviso de seguridad

phpinfo() expone información sensible del servidor (rutas internas, versiones exactas, módulos). Debe borrarse inmediatamente después de la verificación. Nunca lo dejes en un servidor accesible desde internet.

Objetivo. Crear un fichero de prueba que confirme que Apache ejecuta PHP, anotar la versión y borrarlo por seguridad.

Tarea 1 — Crear el fichero (en el servidor).

# Crear el fichero phpinfo.php en el directorio raíz de Apache
echo '<?php phpinfo(); ?>' | sudo tee /var/www/html/phpinfo.php

Tarea 2 — Verificar desde Windows. En el navegador de tu Windows, visita http://IP_DEL_SERVIDOR/phpinfo.php. Debes ver una página larga con tablas de configuración de PHP.

Tarea 3 — Borrar inmediatamente (en el servidor).

sudo rm /var/www/html/phpinfo.php

Recarga la página en el navegador de Windows: debes ver un error 404.

Responde en RESPUESTAS.md, sección ## Paso 2.

¿Qué versión exacta de PHP está instalada? ¿Qué valor tiene la directiva display_errors por defecto? (Búscala con Ctrl+F en la página de phpinfo.)

Captura requerida. Guarda en capturas/paso2_phpinfo.png una captura de la página de phpinfo.php antes de borrarla. Debe verse:

  • La URL http://IP_DEL_SERVIDOR/phpinfo.php en la barra de direcciones.
  • La cabecera con la versión de PHP (por ejemplo "PHP Version 8.3.x").

Verificación.

  • http://IP_DEL_SERVIDOR/phpinfo.php mostraba la página de información de PHP.
  • He borrado /var/www/html/phpinfo.php.
  • Al recargar, http://IP_DEL_SERVIDOR/phpinfo.php devuelve 404.
  • He guardado capturas/paso2_phpinfo.png.

Paso 3 — Estructura del proyecto y VirtualHost

Conceptos

  • No todo el código de una aplicación web debe ser accesible desde el navegador. Solo los ficheros que el navegador necesita ver (páginas de entrada, CSS, JS, imágenes) van en public/. El resto (lógica, datos, plantillas) va fuera de public/ para que nadie pueda accederlo directamente desde una URL.
  • Esta separación es una práctica de seguridad fundamental en toda aplicación web moderna.
  • Un VirtualHost en Apache permite asignar un nombre de dominio local (ej. gestor.local) a una carpeta concreta de tu disco.
  • /etc/hosts permite resolver nombres de dominio sin DNS: añadiendo 127.0.0.1 gestor.local, tu ordenador sabe que gestor.local es él mismo.

Objetivo. Crear la estructura de directorios del proyecto en tu home y configurar Apache para servirlo desde un dominio local gestor.local.

Tarea 1 — Estructura de carpetas.

# Crea el proyecto en tu home (los labs siguientes asumen que se llama gestor)
mkdir -p ~/gestor/{public,src,templates,data}

# Verifica la estructura
ls -R ~/gestor

La salida debe ser algo como:

/home/tuusuario/gestor:
data  public  src  templates

/home/tuusuario/gestor/data:

/home/tuusuario/gestor/public:

/home/tuusuario/gestor/src:

/home/tuusuario/gestor/templates:

Las cuatro subcarpetas están vacías todavía: las iremos rellenando durante los labs.

Para qué sirve cada carpeta (las iremos rellenando en próximos labs)

  • public/ — lo único accesible desde el navegador. Aquí irán index.php, estado.php, hojas CSS, imágenes, etc.
  • src/ — lógica PHP reutilizable (funciones helper). No accesible directamente.
  • templates/ — cabeceras y pies HTML comunes a varias páginas.
  • data/ — ficheros de datos (JSON a partir del lab 08). Nunca accesibles desde el navegador.

Tarea 2 — VirtualHost de Apache.

Crea el fichero de configuración:

sudo nano /etc/apache2/sites-available/gestor.conf

Pega este contenido (sustituye TU_USUARIO por tu nombre de usuario real de la VM; compruébalo con whoami):

<VirtualHost *:80>
    ServerName gestor.local
    DocumentRoot /home/TU_USUARIO/gestor/public

    <Directory /home/TU_USUARIO/gestor/public>
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

Guarda (Ctrl+O, Enter) y sal (Ctrl+X).

Activa el sitio y recarga Apache (sigue en la terminal del servidor):

# Activar el VirtualHost
sudo a2ensite gestor.conf

# Recargar Apache para que coja la nueva configuración
sudo systemctl reload apache2

La IP_DEL_SERVIDOR ya la anotaste en el Paso 1; la seguimos usando aquí.

Tarea 3 — Resolver gestor.local desde Windows.

El VirtualHost ya responde en el servidor, pero si ahora escribes http://gestor.local en el navegador de tu Windows, el navegador no sabrá dónde está ese nombre. Hay que decirle a Windows que gestor.local corresponde a la IP de tu servidor.

Para eso editamos el fichero hosts de Windows (el equivalente de /etc/hosts de Linux):

  1. Abre el Bloc de notas (o cualquier editor de texto) como Administrador:
    • Menú inicio → escribe Bloc de notas → clic derecho sobre el resultado → Ejecutar como administrador.
    • Si Windows te pide confirmación (UAC), acepta.
  2. Dentro del Bloc de notas: ArchivoAbrir y navega a:
    C:\Windows\System32\drivers\etc\hosts
    
    En el diálogo de abrir fichero, cambia el filtro de "Documentos de texto (.txt)" a "Todos los archivos" para que aparezca hosts (no tiene extensión).
  3. Al final del fichero, añade una línea nueva con la IP de tu servidor y el nombre gestor.local:
    IP_DEL_SERVIDOR    gestor.local
    
    Por ejemplo, si tu servidor tiene la IP 192.168.1.42:
    192.168.1.42    gestor.local
    
  4. Guarda el fichero (ArchivoGuardar, o Ctrl+S). Si Windows te da error de permisos, es que no abriste el Bloc de notas como administrador — cierra, ábrelo como administrador y repite.

Para comprobar que Windows ya resuelve el nombre, abre PowerShell o CMD en Windows y ejecuta:

ping gestor.local

Debe responder desde la IP de tu servidor (puede que los paquetes no lleguen si el servidor tiene firewall, pero la línea Haciendo ping a gestor.local [IP_DEL_SERVIDOR] ya te confirma que el nombre se resuelve).

Ahora visita http://gestor.local en el navegador de Windows. Todavía debería dar error (la carpeta public/ está vacía), pero la respuesta debe venir de Apache, no del DNS: un 403 Forbidden o un 404 de Apache significa que el VirtualHost funciona.

Pista si gestor.local no resuelve desde Windows
  • Desde PowerShell/CMD: ping gestor.local. Debe devolver la IP del servidor.
  • Si devuelve "No se encuentra el host": revisa que la línea del hosts de Windows no tenga un # al principio (líneas con # son comentarios) y que el fichero se haya guardado como administrador.
  • Si devuelve una IP distinta de la del servidor: ya tenías otra entrada gestor.local en el hosts; bórrala o coméntala.
  • Desde Windows, comprueba que hay conectividad al servidor con ping IP_DEL_SERVIDOR. Si la IP sí responde pero el nombre no, el problema está en el fichero hosts de Windows.
  • En el servidor, comprueba con sudo apache2ctl configtest que la configuración de Apache no tiene errores.
  • En el servidor, comprueba con sudo apache2ctl -S que gestor.local aparece en la lista de VirtualHosts.

Responde en RESPUESTAS.md, sección ## Paso 3.

¿Por qué es un problema de seguridad tener los ficheros de datos o la lógica de la aplicación dentro de public/? Explica un ejemplo concreto de qué podría pasar.

Captura requerida. Guarda en capturas/paso3_gestor_local.png una captura del navegador al visitar http://gestor.local. Debe verse:

  • La URL http://gestor.local en la barra de direcciones.
  • La respuesta de Apache (aunque sea un 403 o un 404, debe ser visiblemente una página de Apache, no un error de "no se puede resolver el nombre").

Verificación.

  • Existen las carpetas ~/gestor/public/, ~/gestor/src/, ~/gestor/templates/, ~/gestor/data/ en el servidor.
  • /etc/apache2/sites-available/gestor.conf existe en el servidor y apunta a /home/TU_USUARIO/gestor/public.
  • El fichero hosts de Windows (C:\Windows\System32\drivers\etc\hosts) tiene la línea IP_DEL_SERVIDOR gestor.local.
  • Desde PowerShell en Windows, ping gestor.local resuelve a la IP del servidor.
  • Desde el navegador en Windows, http://gestor.local responde (aunque sea con un error de Apache, no con "host no encontrado").
  • He guardado capturas/paso3_gestor_local.png.

Antes del Paso 4 — Cómo editar los ficheros del servidor desde VSCode

Por qué editar por SSH y no en nano

A partir de aquí vamos a escribir ficheros PHP con decenas de líneas. Editarlos con nano o vim desde la terminal de la VM funciona, pero es incómodo: no tienes resaltado de sintaxis, no tienes autocompletado y copiar y pegar trozos largos es propenso a errores.

La forma profesional (y la que ya has usado en otros módulos) es conectar VSCode por SSH a la VM y editar los ficheros como si estuvieran en tu disco local, con todas las ventajas del editor.

Objetivo. Conectar VSCode al servidor Apache por SSH y abrir directamente la carpeta ~/gestor/ para trabajar los siguientes pasos desde el editor, no desde nano.

Tarea.

  1. Asegúrate de que la VM acepta conexiones SSH. Desde la terminal de la VM:

    sudo apt install -y openssh-server
    sudo systemctl enable --now ssh
    ip a       # anota la dirección IP de la VM (normalmente 192.168.x.x)
    

    Verifica desde tu Windows que puedes entrar con SSH (ssh tuusuario@IP_DE_LA_VM) antes de seguir. Si no puedes, revisa el firewall de la VM y la configuración de red en VirtualBox (modo Bridged o NAT con redirección de puertos).

  2. Instala la extensión Remote - SSH de Microsoft en VSCode (si no la tienes ya de actividades anteriores

  3. Conecta VSCode a la VM por SSH:

    • En VSCode: F1Remote-SSH: Connect to Host...Add New SSH Host... → introduce tu_usuario@IP_DE_LA_VM.
    • Selecciona el fichero de configuración (~/.ssh/config suele ser el correcto).
    • Conecta eligiendo el host recién añadido. VSCode abrirá una nueva ventana conectada a la VM.
  4. Abre la carpeta del proyecto: FileOpen Folder... → navega a /home/tuusuario/gestor/ y ábrela. A partir de ahora, cuando crees o edites un fichero en VSCode, se guarda directamente en la VM.

  5. Comprueba que todo funciona: crea un fichero de prueba ~/gestor/public/prueba.txt desde VSCode con un texto cualquiera, cambia a la terminal de la VM y ejecuta cat ~/gestor/public/prueba.txt. Debe verse el contenido que escribiste en VSCode.

  6. Borra el fichero de prueba para no incluirlo en la entrega:

    rm ~/gestor/public/prueba.txt
    
Pista si VSCode no encuentra la VM
  • Desde Windows, lanza ping IP_DE_LA_VM para comprobar que hay conectividad.
  • Si usas VirtualBox en modo NAT, necesitas redirigir el puerto 22 (Configuración de la VM → Red → Avanzadas → Reenvío de puertos → añadir regla para el puerto 22).
  • Lo más cómodo para este módulo es configurar la VM en modo Bridged (adaptador puente) para que tenga IP propia en tu red local.
Pista sobre qué fichero editar para qué
  • Los ficheros .php del proyecto (index.php, etc.) → dentro de ~/gestor/public/, los editas con VSCode abierto en ~/gestor/.
  • Los ficheros de configuración de Apache (como gestor.conf) → dentro de /etc/apache2/sites-available/, requieren sudo. Para estos, sigue usando sudo nano desde la terminal de la VM; VSCode por SSH no tiene permisos de sudo directamente.

A partir de aquí, los siguientes pasos asumen que tienes VSCode abierto en ~/gestor/

Cuando el enunciado diga "crea ~/gestor/public/index.php", lo harás desde VSCode (menú File → New File dentro de la carpeta public/). Cuando tengas que probar el resultado, usas el navegador; cuando tengas que ejecutar un comando del sistema (systemctl, apt, tail -f), usas la terminal de la VM.

Ten ambas ventanas visibles a la vez (VSCode y terminal) — esa es la forma de trabajar real.


Paso 4 — Primer script PHP: index.php

Conceptos

  • PHP se mezcla con HTML: el código PHP va entre <?php ... ?> y el resto es HTML normal.
  • echo imprime texto (como echo en bash). La forma corta <?= $var ?> equivale a <?php echo $var; ?>.
  • Las variables en PHP empiezan por $ y las instrucciones acaban en ;. Paralelismo con bash: en bash nombre="Ana" → en PHP $nombre = "Ana";.
  • htmlspecialchars($var) convierte caracteres peligrosos en HTML seguro. Úsala siempre al mostrar una variable dentro del HTML: si alguien introduce <script>alert(1)</script> como nombre, sin esta función se ejecutaría en el navegador (ataque XSS).

Objetivo. Crear nuestro primer script PHP que genera HTML dinámicamente a partir de variables.

Tarea. Crea el fichero ~/gestor/public/index.php con este contenido:

<?php
// Variables: igual que en bash pero con $ y ; al final.
$titulo      = "Mi gestor de incidencias";
$alumno      = "Tu nombre aquí";
$curso       = "ASIR 2";
$incidencias = 0;
$fecha_hoy   = date("d/m/Y");   // función PHP para la fecha actual
?>
<!DOCTYPE html>
<html lang="es">
<head>
  <meta charset="UTF-8">
  <title><?= htmlspecialchars($titulo) ?></title>
</head>
<body>
  <h1><?= htmlspecialchars($titulo) ?></h1>
  <p>Bienvenido, <?= htmlspecialchars($alumno) ?> (<?= htmlspecialchars($curso) ?>).</p>
  <p>Fecha de hoy: <?= htmlspecialchars($fecha_hoy) ?></p>
  <p>Incidencias registradas: <?= $incidencias ?></p>
</body>
</html>

Guarda y visita http://gestor.local. Deberías ver una página con tu nombre, el curso, la fecha y el número de incidencias.

Ahora personaliza tu página:

  • Sustituye el valor de $alumno por tu nombre real.
  • Añade al menos 2 variables nuevas (por ejemplo $ciudad, $modulo, $mensaje_bienvenida) con sus correspondientes <p> en el HTML.
  • En total, tu index.php debe tener al menos 7 variables declaradas (las 5 de partida más tus 2 añadidas como mínimo).

Recuerda usar htmlspecialchars() en todos los <?= ?> que muestran variables de texto.

Usa Ver código fuente (Ctrl+U) en el navegador para confirmar que lo que llega al navegador es solo HTML, nunca código PHP.

Pista si ves código PHP literal en el navegador

Si en lugar de la página ves texto como <?php $titulo = ..., Apache no está interpretando el .php. Comprueba:

  • sudo a2enmod php8.3 (o la versión que tengas) y después sudo systemctl reload apache2.
  • Que el fichero se llama exactamente index.php (no index.php.txt — Windows a veces añade .txt automáticamente).

Responde en RESPUESTAS.md, sección ## Paso 4.

¿Qué diferencia ves entre el código PHP que escribes y el HTML que recibe el navegador? ¿Ves algún <?php o <?= en "Ver código fuente"?

Captura requerida. Guarda en capturas/paso4_pagina_personal.png una captura del navegador con tu página personalizada. Debe verse:

  • La URL http://gestor.local.
  • Tu nombre real (no "Tu nombre aquí").
  • Al menos 7 valores mostrados (las 5 variables de partida + las 2 nuevas).

Verificación.

  • ~/gestor/public/index.php existe.
  • Tiene al menos 7 variables declaradas.
  • http://gestor.local muestra la página personalizada con tu nombre y los 7+ valores.
  • Todas las variables de texto usan htmlspecialchars().
  • Ver código fuente (Ctrl+U) muestra solo HTML, sin código PHP.
  • He guardado capturas/paso4_pagina_personal.png.

Paso 5 — Depuración: ver los errores de PHP

Conceptos

  • Por defecto PHP oculta los errores (configuración pensada para producción). Durante el desarrollo necesitamos verlos.
  • error_reporting(E_ALL) activa todos los avisos.
  • ini_set('display_errors', '1') los muestra en pantalla.
  • Estas dos líneas van al principio del fichero PHP solo durante el desarrollo.
  • En un servidor real (producción), nunca se muestran errores al usuario: se guardan en logs y el usuario ve una página genérica. El log de Apache está en /var/log/apache2/error.log.

Objetivo. Configurar PHP para mostrar errores durante el desarrollo, provocar un error a propósito para ver cómo aparece, y aprender a leerlo.

Tarea 1 — Activar errores. Edita ~/gestor/public/index.php y añade estas dos líneas justo después de <?php:

1
2
3
4
5
6
<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');

$titulo = "Mi gestor de incidencias";
// ... resto del código ...

Tarea 2 — Provocar un error. Borra el punto y coma del final de una línea, por ejemplo:

$titulo = "Mi gestor de incidencias"   // <-- sin ;
$alumno = "Tu nombre";

Recarga http://gestor.local. Debes ver un mensaje de error que indica el fichero, la línea y el tipo de error (Parse error o syntax error).

Tarea 3 — Ver el log de Apache. En otra terminal, lanza:

sudo tail -f /var/log/apache2/error.log

Recarga la página del navegador y observa qué aparece en la terminal. Sal del tail con Ctrl+C.

Tarea 4 — Corregir el error. Devuelve el ; a su sitio y confirma que la página vuelve a funcionar.

Checkpoint obligatorio antes de seguir

Antes de pasar al Paso 6, ejecuta en el servidor:

php -l ~/gestor/public/index.php

Debe responder No syntax errors detected in .... Si da cualquier otro mensaje, no continúes: tu fichero tiene un error de sintaxis que hará fallar la corrección automática de este lab. Corrige el error y vuelve a lanzar php -l hasta que salga limpio.

Pista sobre leer errores de PHP

El mensaje típico tiene esta forma:

Parse error: syntax error, unexpected token "$alumno", expecting "," or ";"
in /home/tuusuario/gestor/public/index.php on line 6

Te dice qué ha pasado, dónde (fichero) y en qué línea. Siempre que veas un error, léelo entero antes de buscar en Google: el 80 % de las veces el error ya te dice cómo arreglarlo.

Responde en RESPUESTAS.md, sección ## Paso 5.

  1. ¿Qué información te da el mensaje de error de PHP? ¿Indica el fichero y la línea donde está el error?
  2. ¿Por qué NO debemos dejar error_reporting(E_ALL) e ini_set('display_errors', '1') en un servidor de producción?

Captura requerida. Guarda en capturas/paso5_error_php.png una captura del navegador mostrando el mensaje de error antes de corregirlo. Debe verse:

  • La URL http://gestor.local.
  • El mensaje de error con el fichero y la línea indicados.

Verificación.

  • Con el ; eliminado, el navegador muestra un mensaje de error detallado.
  • El mismo error aparece en /var/log/apache2/error.log.
  • He corregido el error y la página vuelve a funcionar.
  • error_reporting(E_ALL) e ini_set('display_errors', '1') están al inicio del fichero final.
  • He guardado capturas/paso5_error_php.png.

Paso 6 — Aplica lo aprendido: panel de diagnóstico del servidor

Qué es este paso

Los cinco pasos anteriores han sido guiados: te he dado los comandos y el código, y tú los has ejecutado. En este sexto paso no hay código de referencia: aplicas lo aprendido en los pasos 4 y 5 (variables, htmlspecialchars(), error_reporting) a un contexto nuevo y cercano a tu trabajo como administrador de sistemas.

La idea es sencilla: un administrador de sistemas necesita a menudo un script que muestre el estado del servidor de un vistazo sin exponer información sensible como hace phpinfo(). Vas a construir uno tú mismo.

Objetivo. Crear un fichero info_servidor.php que muestre información útil sobre el servidor donde corres la aplicación, usando funciones propias de PHP y datos que obtengas ejecutando comandos en la terminal de la VM.

Tarea. Crea ~/gestor/public/info_servidor.php que muestre una página con un panel de diagnóstico.

Requisitos obligatorios de contenido (al menos 8 variables):

  1. Al menos 6 variables cuyo valor se obtiene de funciones o constantes de PHP:

    • $php_version → usando la función phpversion().
    • $sistema_operativo → usando la constante PHP_OS.
    • $hostname → usando la función gethostname().
    • $fecha_hora → usando date('Y-m-d H:i:s').
    • $usuario_actual → usando get_current_user(). Nota: devuelve el usuario propietario del fichero info_servidor.php en el servidor, no el usuario con el que Apache ejecuta el script (que es www-data). Si te sorprende el valor que aparece, es normal.
    • $directorio_actual → usando la constante __DIR__.
  2. Al menos 2 variables cuyo valor obtienes tú en la terminal de la VM y copias como literal al código:

    • $espacio_libre — ejecuta df -h / en la terminal y copia la columna "Avail" (por ejemplo, '12G').
    • $uptime — ejecuta uptime -p en la terminal y copia el resultado (por ejemplo, 'up 3 hours, 14 minutes').

Requisitos de presentación HTML:

  • Un <h1> con el título "Diagnóstico del servidor".
  • Una <table> con dos columnas (cabecera "Parámetro" / "Valor") y una fila por cada variable.
  • Todos los valores mostrados con htmlspecialchars() (son todos cadenas, así que siempre se escapan).

Requisitos de calidad del código:

  • error_reporting(E_ALL) y ini_set('display_errors', '1') al principio del fichero (igual que en el Paso 5).
  • Al menos 3 comentarios en el bloque PHP que expliquen qué hace cada grupo de variables (por ejemplo: "información de PHP", "información del sistema", "datos obtenidos de la terminal").
  • Nombra las variables con sentido.

Visita http://gestor.local/info_servidor.php para comprobar el resultado.

Pista: cómo usar funciones de PHP

Las funciones se llaman con paréntesis, igual que en el Paso 4 usaste date("d/m/Y"). Por ejemplo:

$php_version = phpversion();
$hostname    = gethostname();
$fecha_hora  = date('Y-m-d H:i:s');

Las constantes van sin paréntesis ni $:

$sistema_operativo = PHP_OS;
$directorio_actual = __DIR__;
Pista: cómo obtener el valor de df -h y uptime

En una terminal de la VM, ejecuta:

df -h /

La salida tendrá varias columnas; copia el valor de la columna "Avail" (espacio disponible) de la línea que corresponde a /. Luego:

uptime -p

Copia la cadena completa que devuelve. Mete ambos valores como cadenas literales en el PHP:

$espacio_libre = '12G';                        // lo que te devolvió df
$uptime        = 'up 3 hours, 14 minutes';     // lo que te devolvió uptime -p

Nota: PHP tiene funciones para ejecutar comandos del sistema directamente (shell_exec()), pero son peligrosas si se usan con datos del usuario y las veremos más adelante. De momento, copiar el valor a mano es la opción segura y didáctica.

Nunca dejes info_servidor.php accesible en un servidor público

Igual que phpinfo() del Paso 2, este fichero expone información interna del servidor que no debería ser pública. En un entorno real se protege con autenticación o se limita el acceso por IP. En este lab es solo un ejercicio local.

Responde en RESPUESTAS.md, sección ## Paso 6.

  1. Lista las 8 (o más) variables que has declarado en info_servidor.php, indicando de dónde viene su valor (función PHP, constante PHP, o copiado de la terminal).
  2. Compara este info_servidor.php con el phpinfo.php del Paso 2: ¿cuál de los dos es más peligroso dejar accesible en internet y por qué? Cita al menos dos tipos concretos de información que phpinfo() expone y que tu info_servidor.php no expone.

Captura requerida. Guarda en capturas/paso6_info_servidor.png una captura del navegador visitando http://gestor.local/info_servidor.php. Debe verse:

  • La URL http://gestor.local/info_servidor.php.
  • El título "Diagnóstico del servidor".
  • La tabla con al menos 8 filas (una por variable).

Verificación.

  • ~/gestor/public/info_servidor.php existe y carga en el navegador.
  • Tiene al menos 8 variables.
  • Usa phpversion(), gethostname() y date() al menos.
  • Las variables $espacio_libre y $uptime tienen valores reales copiados de la terminal (no '' ni 'TODO').
  • La página tiene <h1> y <table> con todos los valores.
  • Todos los valores se muestran con htmlspecialchars().
  • error_reporting(E_ALL) está al inicio.
  • He guardado capturas/paso6_info_servidor.png.

Ampliación opcional — HTTPS en local con certificado autofirmado

Para alumnos que terminen pronto

Apache puede servir HTTPS incluso en local usando certificados autofirmados. Esto simula mejor un entorno real.

# Activar el módulo SSL de Apache
sudo a2enmod ssl

# Generar certificado autofirmado (válido 365 días)
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout /etc/ssl/private/gestor.key \
  -out /etc/ssl/certs/gestor.crt

Añade al final de /etc/apache2/sites-available/gestor.conf:

<VirtualHost *:443>
    ServerName gestor.local
    DocumentRoot /home/TU_USUARIO/gestor/public
    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/gestor.crt
    SSLCertificateKeyFile /etc/ssl/private/gestor.key

    <Directory /home/TU_USUARIO/gestor/public>
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

Recarga Apache (sudo systemctl reload apache2) y visita https://gestor.local. El navegador avisará de que el certificado no es de confianza (normal, es autofirmado), pero puedes seguir. Esta ampliación no se corrige.


Checklist final de entrega

Antes de subir el ZIP al Campus, revisa:

  • He creado la carpeta apellido_nombre_lab01/ con mi apellido y nombre reales.
  • Dentro hay gestor/public/index.php con mi código personalizado (al menos 7 variables, todas con htmlspecialchars(), y las dos líneas de error_reporting al principio).
  • Dentro hay gestor/public/info_servidor.php con el panel de diagnóstico del Paso 6.
  • Dentro hay capturas/ con los 6 PNG: paso1_apache_funcionando.png, paso2_phpinfo.png, paso3_gestor_local.png, paso4_pagina_personal.png, paso5_error_php.png, paso6_info_servidor.png.
  • Dentro hay RESPUESTAS.md con las 6 secciones (## Paso 1 a ## Paso 6) rellenas.
  • Tanto index.php como info_servidor.php pasan php -l sin errores.
  • El ZIP se llama apellido_nombre_lab01.zip y al descomprimir aparece una sola carpeta raíz con ese nombre.
  • He subido el ZIP a la tarea correspondiente en el Campus antes de la fecha límite.

Anexo — Plantilla de RESPUESTAS.md

Crea un fichero llamado RESPUESTAS.md dentro de apellido_nombre_lab01/ con esta plantilla:

# Respuestas — Lab 01 Entorno y primer script PHP

**Nombre:** Apellido, Nombre
**Fecha:** YYYY-MM-DD

## Paso 1

(Tu respuesta: versión de Apache instalada — línea "Server version" de `apache2 -v`.)

## Paso 2

(Tu respuesta: versión de PHP y valor por defecto de `display_errors`.)

## Paso 3

(Tu respuesta: por qué es problema de seguridad tener datos o lógica dentro de `public/`, con un ejemplo concreto.)

## Paso 4

(Tu respuesta: diferencia entre el código PHP escrito y el HTML que recibe el navegador; qué ves en "Ver código fuente".)

## Paso 5

1. (Tu respuesta: qué información da el mensaje de error de PHP.)
2. (Tu respuesta: por qué no dejar `display_errors` activo en producción.)

## Paso 6

1. (Tu respuesta: lista de las 8+ variables de `info_servidor.php` con su origen — función PHP, constante PHP o copiado de la terminal.)
2. (Tu respuesta: comparación con `phpinfo.php` del Paso 2 — cuál es más peligroso dejar accesible y dos tipos concretos de información que expone `phpinfo()` y no expone tu `info_servidor.php`.)