1. Contenidos
1.1 Integración de código de servidor con HTML
Una aplicación web dinámica necesita combinar dos tipos de elementos:
- Lenguajes de marcas, como HTML, que describen la estructura del documento que recibirá el navegador.
- Lenguajes de programación en servidor, como PHP, Java, Python, JavaScript/Node.js o C#, que procesan datos y generan la respuesta.
En esta unidad utilizaremos principalmente PHP porque permite integrar código de servidor directamente dentro de un documento HTML.
Ejemplo mínimo
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Ejemplo PHP</title>
</head>
<body>
<h1>Página dinámica</h1>
<?php
$nombre = 'Ana';
?>
<p>Hola, <?= htmlspecialchars($nombre) ?>.</p>
</body>
</html>
Cuando el servidor procesa este fichero, las instrucciones PHP se ejecutan y el resultado se incorpora al documento HTML generado.
El navegador recibiría un contenido equivalente a:
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Ejemplo PHP</title>
</head>
<body>
<h1>Página dinámica</h1>
<p>Hola, Ana.</p>
</body>
</html>
Idea clave: el código PHP forma parte del fichero del servidor, pero no forma parte del documento HTML que recibe normalmente el navegador. El resultado de ejecutar PHP sí se incorpora a la respuesta.
1.2 Generación de HTML desde el servidor
El código de servidor puede generar cualquier parte de un documento HTML: textos, enlaces, listas, tablas, formularios o incluso documentos completos.
Supongamos que disponemos de los siguientes datos:
$productos = [
['nombre' => 'Portátil', 'precio' => 899.99],
['nombre' => 'Monitor', 'precio' => 219.50],
['nombre' => 'Teclado', 'precio' => 79.90]
];
Podemos utilizar PHP para recorrerlos y generar una tabla HTML.
<table>
<thead>
<tr>
<th>Producto</th>
<th>Precio</th>
</tr>
</thead>
<tbody>
<?php foreach ($productos as $producto): ?>
<tr>
<td>
<?= htmlspecialchars($producto['nombre']) ?>
</td>
<td>
<?= number_format($producto['precio'], 2, ',', '.') ?> €
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
El número de filas de la tabla dependerá de los datos disponibles. Si el array contiene diez productos, se generarán diez filas; si contiene cien, se generarán cien.
¿Qué hace PHP en este ejemplo?
- Recorre los datos mediante
foreach.
- Genera una fila HTML por cada producto.
- Inserta los valores dentro de las celdas.
- Entrega al navegador una tabla HTML ya construida.
Importante: HTML no consulta el array ni ejecuta el bucle. Es PHP quien procesa los datos y genera las etiquetas HTML correspondientes.
1.3 Formas habituales de combinar PHP y HTML
PHP permite generar HTML de distintas formas. Técnicamente todas pueden producir el mismo resultado, pero algunas facilitan más la lectura y el mantenimiento del código.
1.3.1 Generar HTML con echo
<?php
$nombre = 'Ana';
echo '<h1>Bienvenida</h1>';
echo '<p>Hola, ' . htmlspecialchars($nombre) . '</p>';
?>
Este enfoque puede resultar adecuado para fragmentos pequeños, pero cuando la estructura HTML crece puede resultar difícil de leer.
1.3.2 Insertar valores PHP dentro de HTML
<?php
$nombre = 'Ana';
?>
<h1>Bienvenida</h1>
<p>Hola, <?= htmlspecialchars($nombre) ?></p>
La sintaxis <?= ... ?> es una forma abreviada de imprimir el resultado de una expresión.
1.3.3 Utilizar sintaxis alternativa para estructuras de control
Cuando una estructura de control contiene HTML, PHP ofrece una sintaxis especialmente legible:
<?php if ($usuarioAutenticado): ?>
<p>Bienvenido al área privada.</p>
<?php else: ?>
<p>Debes iniciar sesión.</p>
<?php endif; ?>
También puede utilizarse con bucles:
<ul>
<?php foreach ($alumnos as $alumno): ?>
<li><?= htmlspecialchars($alumno) ?></li>
<?php endforeach; ?>
</ul>
Esta forma suele ser preferible a imprimir grandes bloques HTML mediante múltiples instrucciones echo.
1.4 Separación entre lógica y presentación
Aunque PHP permita mezclar instrucciones y HTML, hacerlo sin organización puede producir código difícil de mantener.
Podemos distinguir dos responsabilidades:
- Lógica: obtener datos, comprobar condiciones, calcular valores, validar información o decidir qué debe ocurrir.
- Presentación: decidir cómo se muestra esa información mediante HTML.
Ejemplo con lógica mezclada en la presentación
<td>
<?php
if ($producto['stock'] > 0) {
echo '<span class="disponible">Disponible</span>';
} else {
echo '<span class="agotado">Agotado</span>';
}
?>
</td>
El código funciona, pero dentro de la estructura HTML se está tomando una decisión de la aplicación.
Preparación previa de los datos
<?php
$disponible = $producto['stock'] > 0;
$estado = $disponible
? 'Disponible'
: 'Agotado';
$claseEstado = $disponible
? 'disponible'
: 'agotado';
?>
La presentación queda entonces reducida principalmente a mostrar los datos:
<td class="<?= $claseEstado ?>">
<?= $estado ?>
</td>
Esta separación facilita entender qué parte del programa toma decisiones y qué parte construye la interfaz.
Ventajas de separar responsabilidades
- El código resulta más fácil de leer.
- Los cambios en la presentación afectan menos a la lógica.
- La lógica puede reutilizarse con distintas vistas.
- Es más sencillo localizar errores.
- Facilita el trabajo en equipo.
- Prepara el camino hacia arquitecturas como MVC.
Importante: separar lógica y presentación no significa que un fichero PHP no pueda contener HTML. Significa organizar el código para que cada parte tenga una responsabilidad clara.
1.5 De los datos a la vista
En una aplicación sencilla podemos organizar el procesamiento en dos fases:
1. LÓGICA / PREPARACIÓN DE DATOS
PHP
|
+-- obtiene datos
+-- realiza cálculos
+-- comprueba condiciones
+-- prepara variables para mostrar
|
v
2. PRESENTACIÓN
HTML + pequeñas expresiones PHP
|
+-- muestra textos
+-- genera filas
+-- aplica clases
+-- presenta los resultados
Por ejemplo:
<?php
$alumno = [
'nombre' => 'Lucía',
'nota' => 8.2
];
$aprobado = $alumno['nota'] >= 5;
$estado = $aprobado
? 'Aprobado'
: 'Suspenso';
?>
<h1><?= htmlspecialchars($alumno['nombre']) ?></h1>
<p>
Nota:
<strong><?= $alumno['nota'] ?></strong>
</p>
<p>
Resultado:
<strong><?= $estado ?></strong>
</p>
La decisión sobre si el alumno está aprobado se toma antes de generar la vista. La parte HTML se limita a presentar el resultado.
1.6 Servidor web, runtime y servidor de aplicaciones
En una arquitectura web pueden intervenir distintos componentes con responsabilidades diferentes.
| Componente |
Responsabilidad principal |
Ejemplos |
| Servidor web |
Recibir peticiones HTTP, servir recursos y delegar peticiones cuando es necesario. |
Apache, Nginx, IIS, Caddy |
| Runtime / intérprete |
Ejecutar el código escrito en un lenguaje de programación. |
PHP, Python, Node.js, JVM, .NET Runtime |
| Aplicación / servidor de aplicaciones |
Ejecutar la lógica de la aplicación y proporcionar servicios adicionales. |
Aplicaciones Spring Boot, ASP.NET Core, servidores Jakarta EE |
| Base de datos |
Almacenar, consultar y modificar información persistente. |
SQLite, MySQL, PostgreSQL |
Estos componentes pueden encontrarse físicamente en el mismo equipo o distribuidos entre distintas máquinas.
Ejemplo sencillo con PHP
Navegador
|
| HTTP
v
Apache
Servidor web
|
| ejecuta / delega
v
PHP
Runtime
|
| SQL
v
SQLite
Base de datos
Ejemplo con una aplicación Java
Navegador
|
| HTTP
v
Nginx
Servidor web
|
| reenvía petición
v
Aplicación Spring Boot
JVM + lógica de aplicación
|
| SQL
v
PostgreSQL
Base de datos
Recuerda: un servidor web y un servidor de aplicaciones no son conceptos equivalentes. El servidor web está orientado principalmente a gestionar HTTP y recursos web, mientras que un servidor de aplicaciones proporciona un entorno para ejecutar la lógica de una aplicación y ofrecer servicios adicionales.
1.7 Funcionalidades de los servidores de aplicaciones
Cuando las aplicaciones crecen, no resulta suficiente limitarse a ejecutar unas instrucciones y devolver HTML. Es habitual necesitar servicios relacionados con la seguridad, las conexiones, las sesiones o la organización de la aplicación.
Un servidor de aplicaciones o un framework de servidor puede proporcionar funcionalidades como:
- Enrutamiento: asociar URLs con operaciones concretas de la aplicación.
- Gestión de sesiones: mantener información relacionada con un usuario entre distintas peticiones.
- Autenticación y autorización: comprobar quién es el usuario y qué operaciones puede realizar.
- Acceso a datos: gestionar conexiones con bases de datos.
- Gestión de transacciones: asegurar que conjuntos de operaciones se realizan de forma coherente.
- Configuración: centralizar parámetros de la aplicación.
- Registro de actividad: generar logs para supervisar el funcionamiento.
- Gestión de errores: controlar excepciones y producir respuestas adecuadas.
- Servicios web y APIs: generar respuestas HTML, JSON u otros formatos.
En tecnologías actuales algunas de estas funciones son proporcionadas por un servidor de aplicaciones tradicional y otras por el propio framework o runtime.
Idea clave: lo importante no es memorizar una lista de productos, sino reconocer qué responsabilidades necesita una aplicación y qué componente o tecnología las proporciona.
1.8 Resumen de responsabilidades
| Tarea |
Componente habitual |
| Mostrar HTML | Navegador |
| Aplicar CSS | Navegador |
| Ejecutar JavaScript de interfaz | Navegador |
| Recibir inicialmente una petición HTTP | Servidor web o servidor HTTP integrado en la aplicación |
| Ejecutar PHP | Runtime / intérprete PHP |
| Aplicar reglas de negocio | Aplicación de servidor |
| Generar HTML dinámicamente | Código de servidor |
| Consultar datos persistentes | Aplicación mediante la base de datos |
| Almacenar registros | Base de datos |
| Gestionar usuarios, sesiones y permisos | Aplicación / framework / servidor de aplicaciones |