Lección 6: Formularios
Los formularios es la única manera de que el usuario nos transmita información, y tenemos una gran cantidad de posibilidades para recoger: textos, números, archivos, checks…
Para construir nuestro formulario necesitaremos la etiqueta <form>
y dentro todos los <input>
s que necesitemos.
<html>
<body>
<form>
<?php
var_dump($_REQUEST);
?>
<input type="text" name="nombre">
<input type="submit">
</form>
</body>
</html>
Utiliza var_dump($_REQUEST)
para saber que variables te llegan de un formulario.
$_REQUEST
es un array que contiene todas las variables que recibimos, lo cual nos simplifica a la hora de extraer cada elemento.
<html>
<body>
<?php if (isset($_REQUEST['nombre'])): ?>
<p>¿De verdad te llamas <?php echo $_REQUEST['nombre']; ?>? Qué nombre más bonito.</p>
<?php endif; ?>
<form>
<input type="text" name="nombre">
<input type="submit">
</form>
</body>
</html>
La función isset()
te indica si existe cualquier tipo de variable: local, global o dentro de un array
.
Métodos de petición
Existe una gran cantidad de verbos HTTP, o métodos de petición, dentro del desarrollo web:
- GET
- POST
- PUT
- DELETE
- HEAD
- CONNECT
- OPTIONS
- TRACE
- PATH
Todos ellos son como etiquetas que le damos a los datos para marcar su uso. Piensa en ellos como diferentes caminos para llegar al mismo sitio. Imagina que tienes que enviar 2 lámparas a una misma dirección y decides usar 2 compañias de mensajería diferentes: SEUR y CORREOS. Pero le avisas al destinatario que la lámpara que reciba por SEUR es para el salón y la otra tiene una bombilla rota que debe cambiar. Pasado el tiempo, cuando reciba los paquetes, tratará cada lámpara de forma especial. De esta manera puedes enviar varios datos en caminos diferentes para que el destinatario los use de forma distinta.
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
echo 'Llega algo por POST';
}
Método GET
Por defecto un formulario es enviado con el método, verbo, GET
. Tiene una particularidad que no tiene el resto. Pongamos el siguiente código. Yo lo relleno con el nombre “Buda” y la edad “30”. A continuación pulso el botón de enviar.
<html>
<body>
<form method="get">
<input type="text" name="nombre">
<input type="number" name="edad">
<input type="submit">
</form>
</body>
</html>
Si te fijas en la dirección, la URL, verás una ruta parecida a la siguiente.
http://localhost/?nombre=Buda&edad=30
GET
nos permite ver en la barra del URL los datos dándonos la posibilidad de modificarlos.
Cualquier persona observadora podrá ver y modificar los datos. Ten mucho cuidado. Úsalo para información que no comprometa tu sitio: paginadores, mensajes, marcador de idioma…
Para recoger será usando siempre isset()
con $_REQUEST
.
$nombre = isset($_REQUEST['nombre']) ? $_REQUEST['nombre'] : '';
$edad = isset($_REQUEST['edad']) ? $_REQUEST['edad'] : '';
Método POST
El método POST será invisible al ojo del usuario. Recomendable cuando modificamos variables o una base de datos.
<html>
<body>
<form method="post">
<input type="text" name="nombre">
<input type="number" name="edad">
<input type="submit">
</form>
</body>
</html>
Para obtener una varaible get también dispones de $_GET['nombre']
y para post $_POST['nombre']
, pero $_REQUEST['nombre']
simplifica al unificar cualquier elemento que recibamos.
Action
Si no indicas lo contrario, la información se enviará a la misma página donde estemos. Con action
podremos decirle al formulario que lleve los datos a otra URL.
<html>
<body>
<form method="post" action="login.php">
<input type="text" name="nombre">
<input type="number" name="edad">
<input type="submit">
</form>
</body>
</html>
Evitar que se borren los campos
Cada vez que pulsas en un submit
la página se refresca (se realiza una petición) y con ello se reinicia el formulario. ¿Qué pasa si me he equivocado en algún campo? Se pierde como lágrimas en la lluvia. El usuario tendría que volver a rellenarlo. Un truco para solucionarlo sería comprobar si existe el dato, y si es así rellenar su value
.
<html>
<body>
<form>
<input type="text" placeholder="Nombre" name="nombre"<?php if (isset($_REQUEST['nombre']) && $_REQUEST['nombre'] != ''): ?> value="<?php echo $_REQUEST['nombre']; ?>"<?php endif; ?>>
<input type="number" placeholder="Edad" name="edad"<?php if (isset($_REQUEST['edad']) && $_REQUEST['edad'] != ''): ?> value="<?php echo $_REQUEST['edad']; ?>"<?php endif; ?>>
<input type="submit">
</form>
</body>
</html>
Campos ocultos
En ciertas ocasiones necesitaremos enviar por el formulario una información que no sea visible por el usuario: id, token, un histórico, un cálculo, etc. Para ello disponemos de un input
especial con el tipo hidden
.
<html>
<body>
<form>
<input type="hidden" name="maquina-enigma" value="149">
<input type="submit">
</form>
</body>
</html>
En este caso, el visitante solo visualizará un botón pero al enviarse llegará la data maquina-enigma
con el valor 149
.
$codigoSecreto = isset($_REQUEST['maquina-enigma']) ? $_REQUEST['maquina-enigma'] : '';
echo $codigoSecreto;
// 149
También puede ser utilizado para enviar arrays
. Tan solo debemos repetir el name
dejando presente []
.
<html>
<body>
<form>
<input type="hidden" name="filtros[]" value="precio">
<input type="hidden" name="filtros[]" value="valoracion">
<input type="hidden" name="filtros[]" value="fecha">
<input type="submit">
</form>
</body>
</html>
$misFiltros = isset($_REQUEST['filtros']) ? $_REQUEST['filtros'] : [];
var_dump($misFiltros);
// ['precio', 'valoracion', 'fecha']
Aunque también nos podemos apoyar en las funciones serialize()
y unserialize()
. Nos convertirá los arrays en texto o texto en arrays.
echo serialize(['mañana', 'tarde', 'noche']);
// a:3:{i:0;s:7:"mañana";i:1;s:5:"tarde";i:2;s:5:"noche";}
var_dump(unserialize('a:3:{i:0;s:7:"mañana";i:1;s:5:"tarde";i:2;s:5:"noche";}'));
// ['mañana', 'tarde', 'noche']
Estas funciones nos permiten mantener estructuras avanzadas como los diccionarios.
echo serialize(['id' => 234, 'nombre' => 'Sauron']);
// a:2:{s:2:"id";i:234;s:6:"nombre";s:6:"Sauron";}
var_dump(unserialize('a:2:{s:2:"id";i:234;s:6:"nombre";s:6:"Sauron";}'));
// ['id' => 234, 'nombre' => 'Sauron']
Si volvemos al ejemplo anterior, deberemos tener cuidado con las comillas dobles que entrarán en conflicto con las propias de atributo HTML. En su lugar envuelve con comillas simples.
<?php
$filtros = ['precio', 'valoracion', 'fecha'];
?>
<html>
<body>
<form>
<input type="hidden" name="filtros" value='<?= serialize($filtros); ?>'>
<input type="submit">
</form>
</body>
</html>
$filtroSerializados = isset($_REQUEST['filtros']) ? $_REQUEST['filtros'] : '';
$filtroDeserializados = unserialize($filtroSerializados);
var_dump($filtroDeserializados);
// ['precio', 'valoracion', 'fecha']
Es inseguro serializar un string
proviene de un cliente. Se práctica porque es cómodo y rápido para recuperar array
u objetos, aunque lamentablemente debes evitarlo ya que es posible manipular el texto recibido para inyectar código malicioso en el backend. En su lugar recibe un JSON, ya que sus campos son muy limitados, y construye manualmente todos los elementos. Conoce todos los detalles al respecto en PortSwigger.
Una última opción, la cual es actualmente un estándar cuando hablamos de una estructura de datos, es trabajar con JSON.
echo json_encode(['id' => 234, 'nombre' => 'Sauron']);
// {"id":234,"nombre":"Sauron"}
var_dump(json_decode('{"id":234,"nombre":"Sauron"}'));
// ['id' => 234, 'nombre' => 'Sauron']
Si utilizamos el ejemplo anterior quedaría tal que así.
<?php
$filtros = ['precio', 'valoracion', 'fecha'];
?>
<html>
<body>
<form>
<input type="hidden" name="filtros" value='<?= json_encode($filtros); ?>'>
<input type="submit">
</form>
</body>
</html>
$filtroEnJSON = isset($_REQUEST['filtros']) ? $_REQUEST['filtros'] : '';
$filtro = json_decode($filtroEnJSON);
var_dump($filtro);
// ['precio', 'valoracion', 'fecha']
Cada situación posee una mejor solución. La experiencia te guiará cual te conviene utilizar.
Esta obra está bajo una Licencia Creative Commons Atribución-NoComercial-SinDerivadas 4.0 Internacional.
¿Me invitas a un café? ☕
Puedes hacerlo usando el terminal.
ssh customer@andros.dev -p 5555
Comentarios
Nuevo comentario
Nueva replica {{ formatEllipsisAuthor(replyComment.author) }}
Escribe el primer comentario
{{ comments.length }} comentarios