Apuntes php

PHP: Porque a veces necesitas un poco de caos en tu vida.

Lección: Formularios HTML y PHP

Los formularios HTML son la vía natural para que los usuarios envíen datos a tus scripts PHP, ya sea para un libro de visitas, un registro, o una búsqueda. En esta lección aprenderás a crear formularios, procesar sus datos con PHP, validarlos, y protegerlos contra problemas comunes.

Introducción

Los formularios HTML permiten a los usuarios introducir datos que tu script PHP puede procesar. Detrás de muchas aplicaciones PHP (como foros o tiendas online) hay formularios recolectando datos. Para seguir esta lección, deberías conocer etiquetas HTML básicas como <form>, <input>, y <textarea>.

Cuando un usuario envía un formulario, PHP almacena los datos en super variables automáticas ($_POST o $_GET), listas para que las uses en tu script.

Nociones básicas

Un formulario HTML se define con la etiqueta <form> y sus atributos principales: - action: La URL del script PHP que procesará los datos (por ejemplo, form1.php). - method: El método de envío, post (datos ocultos en la solicitud) o get (datos visibles en la URL).

Dentro del formulario, elementos como <input>, <textarea>, o <select> tienen un atributo name. Cuando se envía el formulario, PHP crea variables con esos nombres y los valores introducidos por el usuario.

Ejemplo de formulario (libro de visitas):

<form action="form1.php" method="post">
    Nombre: <input type="text" name="nombre" size="20" /><br>
    Escribe tu mensaje:<br>
    <textarea name="mensaje" cols="40" rows="7"></textarea><br>
    Tu web: <input type="text" name="url" size="20" /><br>
    <input type="submit" name="enviar" value="Click para enviar" />
</form>

Vista renderizada:







Métodos: POST vs. GET

  • POST: Los datos se envían en el cuerpo de la solicitud, no visibles en la URL. Ideal para datos sensibles o largos (por ejemplo, mensajes, contraseñas).
  • GET: Los datos se añaden a la URL (por ejemplo,?nombre=Juan). Útil para búsquedas o enlaces, pero limitado en tamaño y menos seguro.

Ejemplo con GET:

<form action="buscar.php" method="get">
    Buscar: <input type="text" name="query" />
    <input type="submit" value="Buscar" />
</form>

URL resultante: buscar.php?query=php

Procesando formularios en PHP

Los datos del formulario se almacenan en los arrays globales $_POST o $_GET, según el método. Por ejemplo, para el formulario anterior, el script form1.php podría ser:

<?php
declare(strict_types=1);

// Define constantes para nombres de campos
const CAMPO_NOMBRE = "nombre";
const CAMPO_MENSAJE = "mensaje";
const CAMPO_URL = "url";

// Verifica si se envió el formulario
if ($_SERVER["REQUEST_METHOD"] === "POST") {
    $nombre = $_POST[CAMPO_NOMBRE] ?? "";
    $mensaje = $_POST[CAMPO_MENSAJE] ?? "";
    $url = $_POST[CAMPO_URL] ?? "";

    echo "Nombre: " . htmlspecialchars($nombre) . "\n";
    echo "Mensaje: " . htmlspecialchars($mensaje) . "\n";
    echo "URL: " . htmlspecialchars($url) . "\n";
}
?>

Notas: - Usa htmlspecialchars() para evitar ataques XSS (por ejemplo, scripts maliciosos en <textarea>). - Verifica $_SERVER["REQUEST_METHOD"] para procesar solo envíos válidos. - Usa constantes para nombres de campos, mejorando la mantenibilidad.

Validando datos

Siempre valida los datos del formulario para evitar errores o ataques:

<?php
declare(strict_types=1);

if ($_SERVER["REQUEST_METHOD"] === "POST") {
    $nombre = filter_input(INPUT_POST, "nombre", FILTER_SANITIZE_STRING) ?? "";
    $mensaje = filter_input(INPUT_POST, "mensaje", FILTER_SANITIZE_STRING) ?? "";
    $url = filter_input(INPUT_POST, "url", FILTER_SANITIZE_URL) ?? "";

    // Forzar tipo string para seguridad
    $nombre = (string)$nombre;

    // Validaciones
    if (empty($nombre)) {
        echo "El nombre es obligatorio\n";
    } elseif (strlen($nombre) > 50) {
        echo "El nombre es demasiado largo\n";
    } else {
        echo "Datos válidos: " . htmlspecialchars($nombre) . "\n";
    }
}
?>

Notas: - Usa filter_input() para sanitizar datos. - (string) asegura que los datos sean tratados como cadenas. - Verifica campos vacíos y límites (por ejemplo, longitud máxima).

Evitar ataques CSRF (Cross-Site Request Forgery)

Un token CSRF protege tu formulario contra ataques que intentan enviarlo desde otra página maliciosa. Se genera un valor aleatorio y único que se guarda en la sesión, y se espera que llegue con cada formulario enviado.

Para implementar un token CSRF:

  1. Genera un token único y guárdalo en la sesión.
  2. Incluye el token en un campo oculto del formulario.
  3. Al recibir el formulario, verifica que el token enviado coincida con el de la sesión.

Si el token no coincide, detén el script para evitar ataques.

Ejemplo de implementación: creamos el token:

<?php
session_start();
// Creamos un token único y lo guardamos en la sesión
$_SESSION["csrf_token"] = bin2hex(random_bytes(32)); ?>
<form action="form1.php" method="post">
<!-- Campo oculto con el token de seguridad -->
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>" />
<!-- Aquí irían los demás campos del formulario --> </form> 

Verificamos el token al recibir el formulario:

<?php
session_start();
// Verificamos que el token recibido coincida con el de la sesión
if (!isset($_POST["csrf_token"], $_SESSION["csrf_token"]) || $_POST["csrf_token"] !== $_SESSION["csrf_token"])
    {
    // Si no coincide, detenemos el script por seguridad
    die("Error de seguridad: token CSRF inválido.");
    }
    // Si el token es correcto, el formulario es legítimo y podemos continuar
?> 

Ejemplo completo

index.php:

<!DOCTYPE html>
<html>
<head>
    <title>Libro de Visitas</title>
    <style>
        label { display: block; margin: 10px 0; }
        input, textarea { margin-left: 10px; }
    </style>
</head>
<body>
    <h1>Libro de Visitas</h1>
    <form action="index.php" method="post">
        <label>Nombre: <input type="text" name="nombre" size="20" /></label>
        <label>Mensaje:<br><textarea name="mensaje" cols="40" rows="7"></textarea></label>
        <label>Web: <input type="text" name="url" size="20" /></label>
        <input type="submit" name="enviar" value="Enviar" />
    </form>

    <?php
    if ($_SERVER["REQUEST_METHOD"] === "POST") {
        $nombre = filter_input(INPUT_POST, "nombre", FILTER_SANITIZE_STRING) ?? "";
        $mensaje = filter_input(INPUT_POST, "mensaje", FILTER_SANITIZE_STRING) ?? "";
        $url = filter_input(INPUT_POST, "url", FILTER_SANITIZE_URL) ?? "";

        if (empty($nombre) || empty($mensaje)) {
            echo "<p style='color: red;'>Nombre y mensaje son obligatorios</p>";
        } else {
            echo "<h2>Entrada registrada:</h2>";
            echo "<p>Nombre: " . htmlspecialchars($nombre) . "</p>";
            echo "<p>Mensaje: " . htmlspecialchars($mensaje) . "</p>";
            echo "<p>Web: " . htmlspecialchars($url) . "</p>";
        }
    }
    ?>
</body>
</html>

Explicación: - El formulario y el procesamiento están en el mismo archivo (index.php). - Valida campos obligatorios y sanitiza entradas. - Muestra los datos procesados con htmlspecialchars().

TOP