PHP pone a disposición del programador varias superglobales para acceder a los datos que llegan desde el navegador: $_GET para parámetros de URL, $_POST para datos de formularios enviados con el método POST y $_REQUEST como unión de ambas más $_COOKIE. Entender cuándo usar cada una y cómo validar correctamente su contenido es imprescindible para evitar vulnerabilidades.
$_GET: leer parámetros de la URL
$_GET contiene los pares clave-valor que aparecen en la query string de la URL, como ?pagina=2&categoria=php. Es adecuado para búsquedas, filtros y paginación, pero nunca para enviar datos sensibles.
<?php
// URL: /articulos.php?pagina=3&categoria=php
$pagina = isset($_GET['pagina']) ? (int) $_GET['pagina'] : 1;
$categoria = isset($_GET['categoria']) ? trim($_GET['categoria']) : '';
// Validar que la página sea positiva
if ($pagina < 1) {
$pagina = 1;
}
// Sanitizar la categoría antes de usarla en HTML
$categoriaSegura = htmlspecialchars($categoria, ENT_QUOTES, 'UTF-8');
echo "Página: $pagina, Categoría: $categoriaSegura";
?>
$_POST: formularios seguros
$_POST recibe los datos del cuerpo de la petición HTTP. Los valores no aparecen en la URL, lo que los hace adecuados para enviar contraseñas, datos personales o cualquier información que no deba quedar en el historial del navegador.
<?php
// Formulario de contacto con validación básica
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$nombre = trim($_POST['nombre'] ?? '');
$email = trim($_POST['email'] ?? '');
$mensaje = trim($_POST['mensaje'] ?? '');
$errores = [];
if ($nombre === '') {
$errores[] = 'El nombre es obligatorio.';
}
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errores[] = 'El correo electrónico no es válido.';
}
if (strlen($mensaje) < 10) {
$errores[] = 'El mensaje debe tener al menos 10 caracteres.';
}
if (empty($errores)) {
// Procesar el formulario: guardar en BD, enviar email, etc.
echo 'Formulario enviado correctamente.';
}
}
?>
filter_input(): validar en el origen
filter_input() permite leer y validar una variable de entrada en un solo paso, sin tener que acceder directamente a las superglobales. Recibe el tipo de input (INPUT_GET, INPUT_POST, etc.), el nombre del campo y el filtro a aplicar.
<?php
// Leer y validar un entero de GET
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT, [
'options' => ['min_range' => 1]
]);
// $id es false si falla la validación, null si el parámetro no existe
// Leer y sanitizar texto de POST
$nombreLimpio = filter_input(INPUT_POST, 'nombre', FILTER_SANITIZE_SPECIAL_CHARS);
// Validar email
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
if ($email === false || $email === null) {
echo 'Email no válido o no recibido.';
}
// Validar URL
$url = filter_input(INPUT_POST, 'web', FILTER_VALIDATE_URL);
?>
$_REQUEST y por qué conviene evitarlo
$_REQUEST fusiona $_GET, $_POST y $_COOKIE. El orden de precedencia depende de la directiva request_order en php.ini, lo que puede producir comportamientos distintos entre servidores. Un atacante podría manipular el canal de entrada inesperado para sobrescribir un valor. Lo más seguro es usar siempre $_GET o $_POST de forma explícita.
<?php
// Evitar: canal ambiguo
$q = $_REQUEST['q'] ?? ''; // ¿viene de GET, POST o COOKIE?
// Preferible: canal explícito
$q = $_GET['q'] ?? ''; // solo de la URL
$q = $_POST['q'] ?? ''; // solo del cuerpo
// Si necesitas admitir ambos métodos, sé explícito:
$q = ($_SERVER['REQUEST_METHOD'] === 'POST')
? ($_POST['q'] ?? '')
: ($_GET['q'] ?? '');
?>
Salida segura con htmlspecialchars()
Cualquier valor recibido del usuario que se vaya a mostrar en HTML debe escaparse con htmlspecialchars() para prevenir ataques XSS. Convierte caracteres como <, >, " y & en entidades HTML.
<?php
$busqueda = $_GET['q'] ?? '';
// Escapar antes de incluir en HTML
$busquedaHTML = htmlspecialchars($busqueda, ENT_QUOTES, 'UTF-8');
echo "<p>Resultados para: $busquedaHTML</p>";
// Si necesitas usar el valor en un atributo HTML
echo '<input type="text" value="' . $busquedaHTML . '">';
// Combinado con filter_input para máxima seguridad
$pagina = filter_input(INPUT_GET, 'pagina', FILTER_VALIDATE_INT, [
'options' => ['min_range' => 1, 'default' => 1]
]);
echo '<p>Página actual: ' . (int) $pagina . '</p>';
?>
La documentación oficial de $_GET, la de $_POST y la de filter_input() amplían todos los filtros disponibles, opciones de validación y la relación entre estas superglobales y el protocolo HTTP.
