La gestión de formularios es una de las mejores características de PHP. La combinación de HTML para construir formularios, PHP para gestionar datos y MySQL para almacenarlos son una de las tareas mas eficientes.
<form method=POST [action=resp.php] accept-charset='UTF-8'> ... </form>
El flujo básico consiste en capturar la información que el usuario ingresa en los elementos del formulario y enviarla al servidor cuando se ejecuta el evento de envío (submit).
Puede crear el formulario en HTML y la gestión de datos en un script PHP separado asociado con ACTION.
PHP gestiona los datos entrantes mediante arrays superglobales predefinidos.
El método GET pasa argumentos de una pagina a la siguiente como parte de la URL, en formato de pares tipo nombre=valor separando el primero con ? y los siguientes con &. Ej: ?user=juan&cat=5
<Form Method=GET accept-charset='UTF-8'> <input type=text name=nombre> </Form> <?PHP $variable = $_GET['nombre']; $variable = $_REQUEST['nombre']; ?>
Cuidado cuando se usa GET, los datos del formulario enviado serán visibles con la URL de la página
Es el método preferido de envío de formularios porque los pares de valores no son visibles. Los datos viajan ocultos en el cuerpo de la petición HTTP, no aparecen en la URL.
<Form Method=POST accept-charset='UTF-8'> <input type=text name=nombre> </Form> <?PHP $variable = $_POST['nombre']; $variable = $_REQUEST['nombre']; ?>
Define la URL o script .php que recibirá y procesará los datos. Si se deja vacío o no poner action, el formulario se enviará a la misma página.
<form method=GET|POST [action=script.php] [ accept-charset='UTF-8']></form>
<Form Method=GET accept-charset='UTF-8'> <input type=text name=nombre> </Form> <?PHP $variable = $_GET['nombre']; $variable = $_REQUEST['nombre']; ?>
Puede recuperar los datos enviado mediante los métodos: GET o POST con $_REQUEST[]
<Form Method=POST accept-charset='UTF-8'> <input type=text name=nombre> </Form> <?PHP $variable = $_POST['nombre']; $variable = $_REQUEST['nombre']; ?>
Antes de procesar la información, es indispensable comprobar que los campos existan y no contengan valores maliciosos.
//Texto
if (isset($_REQUEST['txt']) and !empty(trim($_REQUEST['txt']))) {
$txt = $_REQUEST['txt'];
}
//Numero
if (isset($_REQUEST['num']) and is_numeric($_REQUEST['num'])) {
$num = round((float) $_REQUEST['num'],2); ;
}
Se llama asi cuando el mismo script contiene el formulario y su gestión de datos.
1. logica PHP 2. formulario
Recuerde que la lógica debera estar siempre antes que la visualización. Es recomendable usar el botón <input type=SUBMIT> como variable de nivel.
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Procesar los datos del formulario de forma segura
$user = $_REQUEST['user'] ?? '';
echo 'Formulario enviado.';
} else {
// Mostrar el formulario limpio por primera vez (petición GET)
echo 'Por favor, completa el formulario.';
}
<?PHP
if (isset($_REQUEST['sem']) and !empty(trim($_REQUEST['sem']))){
$sem = $_REQUEST['sem'];
}else{
$sem = date('YW');
}
echo '<Form>';
echo "<input type=text name=sem value=$sem maxlength=6> Ej 202607";
echo '</Form>';
?>
<?PHP
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// 1. Verificación de existencia
if (isset($_POST['user']) && !empty(trim($_POST['user']))) {
// 2. Sanitización (limpieza contra XSS)
$user = htmlspecialchars(trim($_POST['user']), ENT_QUOTES, 'UTF-8');
// 3. Validación de formato (ejemplo para email)
if (isset($_POST['email'])) {
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
if (!$email) {
echo 'El correo ingresado no es válido.<p>';
}
}
echo 'Hola, '. $user .'<p>';
} else {
echo 'El campo de usuario es obligatorio.<p>';
}
}
echo '<form method=POST>';
echo 'Nombre: <input type=text name=user><p>';
echo 'Correo: <input type=email name=email><p>';
echo '<input type=submit value=Enviar>';
echo '</form>';
?>
Muchas veces recuperamos las opciones de un registro y luego tenemos que seleccionar (SELECTED) la opción adecuada. Una solucion es ir preguntando si se leigio esa opcion miestras construimos el formulario asi:
<select name=cat id=cat>
<option value=H5
<?PHP if ($cat == 'H5'){echo ´ SELECTED´};?>
>Hotel 5
<option value=H4
<?PHP if ($cat == 'H4'){echo ´ SELECTED´};?>
>Hotel 4
<option value=H3
<?PHP if ($cat == 'H3'){echo ´ SELECTED´};?>
>Hotel 3
<option value=H2
<?PHP if ($cat == 'H2'){echo ´ SELECTED´};?>
>Hotel 2
<option value=H1
<?PHP if ($cat == 'H1'){echo ´ SELECTED´};?>
>Hotel 1
<option value=NC
<?PHP if ($cat == 'NC'){echo ´ SELECTED´};?>
>No clasificado
</select>
Pero una solución mucho mas eficiente es usar jQuery asi:
<select name=cat id=cat>
<option value=H5>Hotel 5
<option value=H4>Hotel 4
<option value=H3>Hotel 3
<option value=H2>Hotel 2
<option value=H1>Hotel 1
<option value=NC>No clasificado
</select>
<!-- Selecciono la opción adecuada del select -->
<Script>$('#cat option[value=<?PHP echo $cat; ?>]').attr('selected',true);</Script>
Este especifica las codificaciones de caracteres que se usarán para el envío del formulario. Lo valores comunes con URF-8 o ISO-8859-1.
<Form Method=POST accept-charset='character-set'>
| Elemento | Descripción |
|---|---|
| Input | Con Type se determina su formato: submit, text, checkbox, radio, password, hidden, URL, number, range, file, image, datetime, color, etc. Recuerdo siempre determinar Name. |
| Label | Define una etiqueta para los botones type=input. |
| Button | Con Type se determina el formato: button, submit, etc |
| Select | Define una lista desplegable. |
| Textarea | Use optiman para determinar las opciones. SELECTED para el seleccionado. |
| Keygen | Para facilitar la generación de claves de certificados. |
Nunca use datos sin filtrar en una consulta a BD. Siempre use NAME para cada elemento, al enviar se convertiran en variables. Use VALUE para establecer valores predeterminados.
Elemento para ingresar datos en un formulario.
| Type | Descripción |
|---|---|
| text,email,password | Campos de entra de texto corto |
| number,week,monnth | |
| Checkbox | Selector multiple |
| Radio | Selector unico |
| file | Subida de archivo (requiere enctype='multipart/form-data'). |
| Submit | Botón que dispara el envío del formulario. |
Para limitar al usuario de introducir solo digitos use type=number o type=range.
<input type=number name=num value=50.0 min=0 max=100 step=0.1>
Los elementos tipo checkbox y radio son especiales al enviar formulario porque solo se envian si estan marcados.
Para asociar una etiqueta a un elemento.
<label for=val1>Nombre:</label><br> <input type=text name=nom id=val1><
<form> <label for=nom>Nombre:</label><br> <input type=text name=nom id=nom><br> <label for=ape>Apellido:</label><br> <input type=text name=ape id=ape> </form>
Botón que no tiene ninguna funcionalidad.
<button>Mensaje</button>
<button onClick='alert("Hola mundo")'>Envia mensaje</button>
Si lo añadimos dentro de un formulario mágicamente asumirá el rol de botón para enviar formulario (submit).
Menú desplegable de opciones
<Select name=filter title='Selecciona una moneda' required> <option value='' disabled selected hidden>--- elige una moneda --- <option value=S>Soles <option value=D>Dolares <option value=E>Euros </Select>
Para que un select sea required tienes que poner el primer valor en vacio.
Opciones acotadas sin menú desplegable.
<input list=navegadores name=nav>
<datalist id=navegadores>
<option value=Edge>
<option value=Firefox>
<option value=Chrome>
<option value=Opera>
<option value=Safari>
</datalist>
Entrada de texto de múltiples líneas.
<textarea name=txt [rows=x] [cols=y] [maxlenght=n] [wrap]></textarea>
En PHP, $_SERVER['REQUEST_METHOD'] es una variable superglobal que devuelve el método de petición HTTP usado para acceder a la página actual. Se usa principalmente para detectar cómo interactuó el usuario con tu script (por ejemplo, cargando la página normalmente o enviando un formulario). Posibles respuestas: GET, POST, PUT, PATCH o DELETE.
$metodo = $_SERVER['REQUEST_METHOD'];
switch ($metodo) {
case 'GET':
// Obtener y mostrar datos
break;
case 'POST':
// Crear un nuevo registro
break;
case 'PUT':
// Reemplaza el registro completo (mas pesado)
break;
case 'PATCH':
// Actualizar parcialmente un registro existente (mas ligero)
break;
case 'DELETE':
// Eliminar un registro
break;
default:
// Método no permitido
http_response_code(405);
}
<html>
<Body>
<?php
if ($exito){
echo '<div class=alerta-exito>';
echo 'Mensaje enviado correctamente. Nos pondremos en contacto pronto.</div>';
}
?>
<!-- novalidate evita que el navegador intercepte la validación para probar PHP -->
<form action="<?= htmlspecialchars($_SERVER['PHP_SELF']); ?>" method=POST novalidate>
<div class=campo>
<label for=nombre>Nombre:</label>
<input type=text id=nombre name=nombre value='<?= $nombre; ?>'>
<?php if (isset($errores['nombre'])): ?>
<span class=error-msg><?= $errores['nombre']; ?></span>
<?php endif; ??>
</div>
<div class=campo>
<label for=email>Correo Electrónico:</label>
<input type=email id=email name=email value='<?= $email; ??>'?>
<?php if (isset($errores['email'])): ??>
<span class=error-msg><?= $errores['email']; ??>?</span?>
<?php endif; ??>
</div>
<div class=campo>
<label for=mensaje>Mensaje:</label>
<textarea name=mensaje id=mensaje rows=4><?= $mensaje; ?></textarea>
<?php if (isset($errores['mensaje'])): ??>
<span class=error-msg><?= $errores[mensaje]; ??></span?>
<?php endif;?>
</div>
<button type=submit>Enviar</button>
</form>
</body>
</html>
Alunas funciones utiles de PHP y MySQL para seguridad.
| Funcion | Descripción |
|---|---|
| trim() | Borra los espacios en blanco invisibles que el usuario pudo haber dejado sin querer al inicio o al final del correo. |
| htmlspecialchars() | Evita ataques de XSS (Cross-Site Scripting). Si un atacante escribe código malicioso en un formulario (como <script>alert('hacked')</script>), esta función lo transforma en texto inofensivo para que no se ejecute en tu base de datos o pantalla. Te protege contra JavaScript. |
| $mysqli-%gt;escape_string() | Proyege contra Inyección SQL. Escapa caracteres especiales (como las comillas ' o ") para que el motor de la base de datos los interprete como simple texto y no como código SQL malicioso. |
| $mysqli-%gt;prepare() | |
| bind_param() | |
Si guardas datos usando htmlspecialchars() en la base de datos: Estás alterando los datos originales de forma innecesaria (un nombre con comillas se guardará deformado con códigos como "). Además, no te protege adecuadamente de ciertos tipos de inyección SQL.
$nom = trim($_REQUEST['nom'] ?? ''); // Al momento de mostrarlo en el HTML, usas htmlspecialchars() echo 'Hola, '. htmlspecialchars($nom, ENT_QUOTES, 'UTF-8');
Si muestras datos en HTML usando $mysqli-%gt;escape_string: No te servirá de nada. El código <script> se ejecutará en el navegador del usuario y tu web será hackeada.
$nom = trim($_REQUEST['nom'] ?? '');
// Preparar la consulta (Inmune a Inyección SQL)
$sql = $mysqli-?>prepare('INSERT INTO usuarios (nom) VALUES (?)');
$sql-?>bind_param('s',$nom); // El driver se encarga de la seguridad automáticamente
$sql-?>execute();
Antes de ingresar los datos en una BD es necesario validar el tipo de datos y su existencia.
| Funcion | Descripcion |
|---|---|
| ctype_alnum | Chequear posibles caracteres alfanuméricos |
| ctype_alpha | Chequear posibles caracteres alfabéticos |
| ctype_space | Chequear posibles caracteres de espacio en blanco |
| ctype_upper | Chequear posibles caracteres en mayúscula |
| ctype_lower | Chequear posibles caracteres en minúscula |
| ctype_graph | Chequear posibles caracteres imprimibles, con excepción de los espacios |
| ctype_print | Chequear posibles caracteres imprimibles |
| ctype_punct | Chequear posibles caracteres imprimibles que no son ni espacios en blanco ni caracteres alfanuméricos. |
| ctype_cntrl | Chequear posibles caracteres de control |
| ctype_digit | Chequear posibles caracteres numéricos |
| ctype_xdigit | Chequear posibles caracteres que representen un dígito hexadecimal |
//Cadenas
if (isset($_REQUEST['txt']) and is_string($_REQUEST['txt'])){
$txt = trim($_REQUEST['txt']);
}
//Numeros
if (isset($_REQUEST['num']) and is_numeric($_REQUEST['num'])){
$num = (int) $_REQUEST['num'];
}
| Funcion | Descripcion |
|---|---|
| is_string | Determina si una variable es de tipo cadena (string) |
| is_numeric | Determina si una variable es una cadena numérica |
| is_int | Determina si una variable es de tipo integer |
| is_integer | Alias de is_int |
| is_long | Alias de is_int |
| is_float | Determina si una variable es de tipo float |
| is_double | Alias de is_float |
| is_real | Alias de is_float |
| is_countable | Verifica si el contenido de la variable es un valor contable |
| is_null | Indica si una variable es null |
| is_object | Determina si una variable es de tipo objeto |
| is_array | Determina si una variable es un array |
| is_bool | Determina si una variable es un bool |
| is_callable | Determina si un valor puede ser llamado como una función en el ámbito actual |
| is_iterable | Determina si el contenido de la variable es iterable. |
| is_resource | Determina si una variable es un recurso |
| is_scalar | Indica si una variable es un escalar |