6. Forms
Forms are the only way for the user to send us information, and we have a huge range of possibilities to collect: text, numbers, files, checkboxes...
To build our form we will need the <form> tag and, inside it, all the <input>s we need.
<html>
<body>
<form>
<?php
var_dump($_REQUEST);
?>
<input type="text" name="nombre">
<input type="submit">
</form>
</body>
</html>
Use
var_dump($_REQUEST)to find out which variables reach you from a form.
$_REQUEST is an array containing all the variables we receive, which makes it simpler for us to extract each element.
<html>
<body>
<?php if (isset($_REQUEST['nombre'])): ?>
<p>Is your name really <?php echo $_REQUEST['nombre']; ?>? What a beautiful name.</p>
<?php endif; ?>
<form>
<input type="text" name="nombre">
<input type="submit">
</form>
</body>
</html>
The
isset()function tells you whether any kind of variable exists: local, global or inside anarray.
Request methods
There are a large number of HTTP verbs, or request methods, in web development:
- GET
- POST
- PUT
- DELETE
- HEAD
- CONNECT
- OPTIONS
- TRACE
- PATH
They are all like labels we attach to the data to mark its use. Think of them as different paths to reach the same place. Imagine you have to send 2 lamps to the same address and you decide to use 2 different courier companies: SEUR and CORREOS. But you warn the recipient that the lamp arriving via SEUR is for the living room and that the other one has a broken bulb they must replace. Later on, when they receive the parcels, they will treat each lamp in a special way. This way you can send several pieces of data along different paths so that the recipient uses them differently.
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
echo 'Something arrives via POST';
}
GET method
By default a form is submitted with the GET method, or verb. It has a particularity that the others do not have. Let's take the following code. I fill it in with the name "Buda" and the age "30". Then I press the submit button.
<html>
<body>
<form method="get">
<input type="text" name="nombre">
<input type="number" name="edad">
<input type="submit">
</form>
</body>
</html>
If you look at the address, the URL, you will see a path similar to the following.
http://localhost/?nombre=Buda&edad=30
GET lets us see the data in the URL bar, giving us the ability to modify it.
Any observant person will be able to see and modify the data. Be very careful. Use it for information that does not compromise your site: paginators, messages, language marker...
To collect it you will always use isset() with $_REQUEST.
$nombre = isset($_REQUEST['nombre']) ? $_REQUEST['nombre'] : '';
$edad = isset($_REQUEST['edad']) ? $_REQUEST['edad'] : '';
POST method
The POST method will be invisible to the user's eye. Recommended when we modify variables or a database.
<html>
<body>
<form method="post">
<input type="text" name="nombre">
<input type="number" name="edad">
<input type="submit">
</form>
</body>
</html>
To get a get variable you also have
$_GET['nombre']available, and for post$_POST['nombre'], but$_REQUEST['nombre']simplifies things by unifying any element we receive.Security note: Although
$_REQUESTis convenient, in professional applications it is better to use$_GETor$_POSTexplicitly. Why? Because$_REQUESTmixes GET, POST and COOKIES, which can cause confusion about the real origin of the data. If your code expects data via POST (like a login form) but someone sends it via GET (visible in the URL), you could have security problems. Use$_REQUESTonly when you really do not care where the data comes from. For authentication forms, payments, or any sensitive operation, always use$_POSTor$_GETexplicitly.
Action
If you do not specify otherwise, the information will be sent to the same page we are on. With action we can tell the form to take the data to another 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>
Preventing fields from being cleared
Every time you click a submit the page refreshes (a request is made) and with it the form resets. What happens if I made a mistake in some field? It is lost like tears in the rain. The user would have to fill it in again. A trick to solve this would be to check whether the data exists, and if so, fill in its value.
<html>
<body>
<form>
<input type="text" placeholder="Name" name="nombre"<?php if (isset($_REQUEST['nombre']) && $_REQUEST['nombre'] != ''): ?> value="<?php echo $_REQUEST['nombre']; ?>"<?php endif; ?>>
<input type="number" placeholder="Age" name="edad"<?php if (isset($_REQUEST['edad']) && $_REQUEST['edad'] != ''): ?> value="<?php echo $_REQUEST['edad']; ?>"<?php endif; ?>>
<input type="submit">
</form>
</body>
</html>
Hidden fields
On certain occasions we will need to send information through the form that is not visible to the user: id, token, a history, a calculation, etc. For this we have a special input with the type hidden.
<html>
<body>
<form>
<input type="hidden" name="maquina-enigma" value="149">
<input type="submit">
</form>
</body>
</html>
In this case, the visitor will only see a button, but when it is submitted the data maquina-enigma will arrive with the value 149.
$codigoSecreto = isset($_REQUEST['maquina-enigma']) ? $_REQUEST['maquina-enigma'] : '';
echo $codigoSecreto;
// 149
It can also be used to send arrays. We just have to repeat the name, keeping [] present.
<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']
We can also rely on the serialize() and unserialize() functions. They will convert arrays into text or text into 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']
These functions let us keep advanced structures such as dictionaries.
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']
If we go back to the previous example, we must be careful with the double quotes, which will conflict with the HTML attribute's own quotes. Instead, wrap it with single quotes.
<?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']
It is insecure to serialize a
stringthat comes from a client. It is practiced because it is convenient and fast for retrievingarrays or objects, although unfortunately you should avoid it since it is possible to manipulate the received text to inject malicious code into the backend. Instead, receive a JSON, since its fields are very limited, and build all the elements manually. Learn all the details about it at PortSwigger.
One last option, which is currently a standard when we talk about a data structure, is to work with JSON.
echo json_encode(['id' => 234, 'nombre' => 'Sauron']);
// {"id":234,"nombre":"Sauron"}
var_dump(json_decode('{"id":234,"nombre":"Sauron"}'));
// ['id' => 234, 'nombre' => 'Sauron']
If we use the previous example it would look like this.
<?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']
Each situation has a better solution. Experience will guide you as to which one to use.
Activity 1
Let's build a system that calculates the price of a newsletter service for us. Depending on the number of emails we send, it will cost one price or another. Below you can see a table.
| From | To | Price |
|---|---|---|
| 0 | 2000 | 0 € |
| 2001 | 10000 | 0.7 € per unit |
| 10001 | Infinity | 0.2 € per unit |
- Add a field to indicate the number of emails to send. Check that it is a number.
- Add an option to indicate whether you want insurance for each message, which will have a surcharge of 0.1 € per message.
- When clicking
submit, show the total price.
Activity 2
The goal will be to create various search tools to find our ideal apartment.
Store several pieces of data in a dictionary with the following structure.
- Price/night. Check that it is a number.
- City. Check that it is a text.
- Wifi. Check that it exists.
- Website. Check that it is a valid domain.
For example.
$apartamentos =[
[
'precio/noche' => 37,
'ciudad' => 'Valencia',
'wifi' => True,
'pagina web' => 'https://hotel.com'
],
[
'precio/noche' => 87,
'ciudad' => 'Madrid',
'wifi' => False,
'pagina web' => 'https://motel.es'
],
...
];
Build a different form for each field. Print the results in a nice and human way.
Pro:
- Calculate the average price of the results (you can use
array_reduce()).
This work is under a Attribution-NonCommercial-NoDerivatives 4.0 International license.
Desafíos de programación atemporales y multiparadigmáticos
Te encuentras ante un librillo de actividades, divididas en 2 niveles de dificultad. Te enfrentarás a los casos más comunes que te puedes encontrar en pruebas técnicas o aprender conceptos elementales de programación.
Buy the bookWill you buy me a coffee?
This is how I keep writing without ads or paywalls.
Sure, it's on me!
Comments
There are no comments yet.