En cualquiera de los 9 proyectos, HTML es la capa que el usuario ve y toca primero: el formulario donde escribe un dato, la tabla donde aparece la lista de resultados, el botón que dispara la acción. Todo lo que JS y PHP hacen "detrás" necesita un lugar en HTML donde mostrarse.
Piensa en HTML como los cajones vacíos de un mueble: tú defines cuántos cajones hay y de qué tamaño, pero lo que se guarda dentro (los datos) lo pone JS o PHP después.
<html> envuelve todo el documento. lang="es" indica el idioma (ayuda a lectores de pantalla y buscadores).<h1> es un encabezado de nivel 1 (el más grande/importante). Existen h1 a h6.body y html en orden inverso a como se abrieron.<tag>) se debe cerrar (</tag>), excepto las "vacías" como <input>, <img>, <br>.<form>.action = a qué archivo se envían los datos. method="POST" = los datos viajan ocultos en el cuerpo de la petición (no en la URL como GET).<label> es el texto descriptivo del campo. for lo conecta con el id del input (mejora accesibilidad: al hacer clic en el texto, se enfoca el campo).type define el tipo de campo. name es la clave con la que PHP/JS van a leer ese valor ($_POST['nombre']). required obliga a llenarlo antes de enviar.type="submit" hace que al hacer clic se envíe todo el formulario al action indicado arriba.<form> y </form> viaja junto al enviarse.name es el que importa para recuperar datos en el backend — no el id. Es un error común confundirlos.| Sintaxis | Para qué sirve | Ejemplo de uso en tus proyectos |
|---|---|---|
| <input type="text"> | Texto libre corto | Nombre de tarea, nombre de contacto |
| <input type="number"> | Solo números, con flechas +/- | Nota de estudiante, cantidad de producto |
| <input type="email"> | Valida formato de correo automáticamente | Correo en agenda de contactos |
| <input type="checkbox"> | Sí/No, marcado o no marcado | Tarea completada, presente/ausente |
| <select><option> | Lista desplegable de opciones fijas | Elegir candidato a votar, elegir categoría |
| <textarea> | Texto libre largo, varias líneas | Descripción de producto |
| <table><tr><td> | Mostrar datos en filas y columnas | Listar todos los registros guardados |
name, ese dato no llega al servidor.id, no por name.JS es ideal para todo lo que debe sentirse inmediato: validar que un campo de nota esté entre 0 y 5 antes de enviarlo, sumar el total del carrito mientras el usuario agrega productos, recorrer un array y construir filas de tabla dinámicamente.
Diferencia clave con PHP: si cierras el navegador, todo lo que hizo JS se pierde. JS no guarda nada de forma permanente por sí solo — para eso existe PHP + base de datos.
let declara una variable que puede cambiar de valor después. "Ana" es un string (texto), siempre entre comillas.const declara una variable constante — su valor nunca cambia. Se usa para valores fijos como tasas o límites.true o false. Ideal para "completado / no completado", "presente / ausente".[], separados por comas. Vas a usarlo en los 9 proyectos.document es la página completa. getElementById busca el elemento HTML cuyo id="nombre" y lo guarda en la variable..value obtiene lo que el usuario escribió dentro de ese input.<p id="resultado"></p> vacío en el HTML).innerHTML reemplaza el contenido de ese elemento con el texto/código que le asignes. Así "pintas" resultados en pantalla.addEventListener = "escucha este tipo de evento". "click" es el evento. La función que sigue se ejecuta cada vez que ocurre el clic.addEventListener.onclick="miFuncion()" directamente en el HTML del botón. Es más simple para empezar, aunque addEventListener es más recomendado a mediano plazo.if evalúa una condición. Si es verdadera (true), entra al bloque { }. >= significa "mayor o igual que".console.log imprime en la consola del navegador (F12).else = "si la condición de arriba fue falsa, haz esto en su lugar".else.| Operador | Significado |
|---|---|
| === | Igual a (compara valor Y tipo — siempre prefiere este sobre ==) |
| !== | Diferente de |
| > / < | Mayor que / Menor que |
| >= / <= | Mayor o igual / Menor o igual |
| && | Y lógico — ambas condiciones deben ser verdaderas |
| || | O lógico — basta con que una sea verdadera |
i = 0: empieza en la posición 0. i < numeros.length: continúa mientras i sea menor que el tamaño del array. i++: suma 1 a i en cada vuelta.numeros[i] accede al elemento en la posición i. Se va sumando a la variable acumuladora.suma contiene el total de los 3 números.numeros.forEach(n => suma += n) hace lo mismo en una línea, pero entender el for clásico primero te ayuda a entender qué pasa "por debajo".fetch(). Esto es opcional para proyectos básicos (un <form> normal también funciona), pero es bueno conocerlo.fetch hace una petición a otro archivo (aquí, un PHP) sin recargar la página actual.JSON.stringify convierte un objeto JS en texto plano (formato JSON) para poder enviarlo..then() se ejecuta cuando la respuesta del servidor llega. Aquí solo la imprime en consola.PHP es lo que hace que tus datos sobrevivan después de cerrar el navegador. Si quieres que tu lista de tareas siga existiendo cuando vuelvas a abrir la página, PHP (guardando en un array de sesión o en MySQL) es indispensable.
Flujo típico: el usuario llena un <form> en HTML → lo envía → PHP recibe los datos → los procesa/guarda → PHP responde con HTML actualizado.
<?php y ?>.$. No se declara tipo: PHP lo detecta solo.echo imprime un valor directamente en el HTML de salida..php, no en .html — si no, el servidor no lo ejecuta, solo lo muestra como texto.<form method="POST"> se envía, PHP recibe los valores en la variable superglobal $_POST.isset() verifica que ese campo realmente venga en la petición (evita errores si llegan al archivo sin enviar el formulario).$_POST['nombre'] — el texto 'nombre' debe coincidir exactamente con el name="nombre" del input en el HTML.if y el bloque PHP.| Variable | Cuándo se usa |
|---|---|
| $_POST | Datos enviados con method="POST" (lo más usado en tus proyectos) |
| $_GET | Datos enviados por la URL (ej: pagina.php?id=3) |
| $_SESSION | Datos que persisten mientras el usuario navega (requiere session_start()) |
"nombre", "nota") — ideal para representar un registro con varios campos.foreach recorre cada elemento del array sin necesitar un índice manual — es la forma más usada en PHP para listas."localhost" significa "el mismo servidor donde corre el PHP".new mysqli(...) crea la conexión usando los 4 datos anteriores en ese orden exacto.-> accede a una propiedad/método de un objeto (aquí, el objeto conexión). connect_error contiene el mensaje de error si algo falló.die() detiene la ejecución y muestra el mensaje. El punto . en PHP concatena texto (equivalente al + de JS para strings).prepare() crea una consulta con un placeholder ? en vez de escribir el valor directo — esto previene inyección SQL (un ataque común).bind_param conecta el valor real a ese ?. "s" indica el tipo: s=string, i=integer, d=decimal."INSERT INTO tareas VALUES ('" . $titulo . "')" directo con el dato del usuario metido en el texto — eso es inyección SQL, una vulnerabilidad grave. Siempre usa prepare() + bind_param().La idea no es que reemplaces tu proyecto PHP — es ver la misma lógica (sumar un array, validar una condición, mostrar resultados) resuelta en un lenguaje tipado. Esto te prepara para Laravel/.NET más adelante y te hace notar qué partes de la lógica son universales (los if, los bucles) y cuáles son específicas de cada lenguaje (la sintaxis).
var para que el compilador lo infiera).using importa una librería. System trae funciones básicas como Console.class (clase). No existe código "suelto" como en PHP.Main() es el punto de entrada: lo primero que se ejecuta al correr el programa. void indica que no devuelve ningún valor.string = texto. A diferencia de JS, esto no puede luego guardar un número.int = número entero. Otros tipos comunes: double (decimales), bool (true/false).Console.WriteLine imprime en pantalla (equivalente a echo en PHP). El $"..." permite insertar variables directamente con {} — se llama interpolación de strings.Main.Programa.List<int> es una lista que solo puede contener enteros (el tipo va entre <>). Es el equivalente al array de PHP/JS pero con tipo fijo.foreach recorre cada elemento. Nota: en C# se usa in, mientras en PHP es as — mismo concepto, distinta palabra clave.+= es un atajo para suma = suma + n. También existe en JS y PHP.foreach.(double) es un cast: convierte el entero a decimal antes de dividir, para no perder los decimales. .Count es el tamaño de la lista (equivalente a .length en JS)..cshtml que mezclan HTML con C#, de forma parecida a como PHP mezcla HTML con su propio código.@page es obligatorio al inicio: le dice a ASP.NET que este archivo es una página Razor accesible por URL.asp-for es un atributo especial de ASP.NET que conecta este input directamente con una propiedad Nombre de la clase C#.PageModel, lo que le da las capacidades necesarias para responder a peticiones web.[BindProperty] es un atributo que conecta automáticamente esta propiedad con el input del formulario que tenga el mismo asp-for.{ get; set; } convierte esto en una propiedad (se puede leer y escribir desde fuera de la clase).OnPost() se ejecuta automáticamente cuando el formulario se envía con method="post". Es el equivalente al bloque que procesa $_POST en PHP.OnPost, la propiedad Nombre ya tiene el valor que el usuario escribió — sin necesidad de leer un array como $_POST manualmente.$_POST['nombre'] en PHP ≈ propiedad con [BindProperty] + asp-for en ASP.NET. La diferencia es que ASP.NET conecta automáticamente el campo con la propiedad, mientras en PHP tú accedes manualmente al array.| Concepto | PHP | C# |
|---|---|---|
| Variable | $nombre = "Ana"; | string nombre = "Ana"; |
| Imprimir | echo $nombre; | Console.WriteLine(nombre); |
| Concatenar texto | "Hola " . $nombre | $"Hola {nombre}" |
| Array/Lista | $arr = [1,2,3]; | List<int> arr = new List<int>{1,2,3}; |
| Recorrer lista | foreach ($arr as $x) | foreach (int x in arr) |
| Recibir datos de form | $_POST['campo'] | [BindProperty] + asp-for |
| Tipado | Dinámico (no se declara tipo) | Estático (tipo obligatorio) |
guardar.php — ese es el archivo que va a recibir estos datos cuando se envíe.name="nombre" es la clave que PHP usará para leer este valor. El id es para que JS lo pueda ubicar si hace falta validar algo antes de enviar.name="edad" es la clave que usará PHP.onclick="return validar()" ejecuta una función JS antes de enviar. Si esa función devuelve false, el envío se cancela y nunca llega a PHP.edad es mayor a 0, devuelve true (se envía el formulario). Si no, false (se bloquea el envío). Aquí termina el trabajo de HTML+JS en este recorrido.action="guardar.php" del formulario de arriba. Todo lo que está aquí corre en el servidor, no en el navegador.'nombre' coincide exactamente con el name="nombre" del input en el HTML — así es como PHP sabe cuál valor leer.FILE_APPEND agrega la línea sin borrar lo anterior. (En un proyecto real, esto sería un INSERT a MySQL en vez de un archivo de texto.)| Tecnología | ¿Dónde corre? | ¿Qué tan permanente es lo que hace? |
|---|---|---|
| HTML | Navegador (cliente) | Se pierde al recargar — solo estructura |
| JavaScript | Navegador (cliente) | Se pierde al cerrar/recargar la pestaña |
| PHP | Servidor | Puede persistir si guarda en archivo o BD |
| MySQL | Servidor (motor de base de datos) | Permanente hasta que algo lo borre explícitamente |
| C# / ASP.NET | Servidor (equivalente directo a PHP) | Igual que PHP: permanente si se conecta a una BD |
<form> envía y la página recarga completa mostrando el HTML que PHP genera. Es el código que ya viste completo en 05.1. Más fácil de depurar al inicio.fetch(), y pinta la respuesta sin recargar nada. Más moderno, una capa más de código. Código abajo.<form> no lleva action ni method — JS va a tomar control total del envío, así que esos atributos ya no se necesitan.name porque PHP no va a leer $_POST directo de un form enviado — JS va a leer este valor con .value y armarlo él mismo.type="button" en vez de "submit" — así el botón no intenta enviar el formulario de la forma tradicional; todo el control queda en manos de JS..text() lee la respuesta como texto plano. El segundo .then() toma ese texto y lo coloca dentro de <p id="resultado"> — la página nunca se recargó.$_GET porque el dato llegó pegado en la URL (como armó el fetch de arriba), no por $_POST.<input> de tu HTML.if.