web php
Forms
For junior PHP work, forms are a core skill. You need to understand the HTML shape, how values arrive in PHP, how to preserve user input after an error, and why form input must never be trusted just because it came from your own page.
The basic shape
A form needs an action, a method, and inputs with name attributes:
<form method="post" action="/contact">
<label for="email">Email</label>
<input id="email" name="email" type="email">
<label for="message">Message</label>
<textarea id="message" name="message"></textarea>
<button type="submit">Send</button>
</form>
The name attribute is what PHP receives. The id is useful for connecting labels to inputs, but id="email" does not submit a value by itself. Without name="email", PHP will not receive the email field.
GET forms and POST forms
Use GET when the form is asking for a view of information and the result can be bookmarked or shared. Search and filters are common examples.
<form method="get" action="/products">
<label for="q">Search</label>
<input id="q" name="q" type="search">
<button type="submit">Search</button>
</form>
Submitting this can produce a URL such as /products?q=boots. PHP reads the value from $_GET.
Use POST when the form changes server state: login, register, create, update, delete, checkout, comment, upload, or profile change. PHP reads normal POST form fields from $_POST.
Rendering a form with PHP
When a form fails validation, users should not have to retype everything. Preserve safe submitted values by escaping them back into the form.
<?php
declare(strict_types=1);
function e(string $value): string
{
return htmlspecialchars($value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}
$old = [
'email' => 'ada@example.com',
'message' => 'Hello <team>',
];
echo '<input name="email" value="' . e($old['email']) . '">' . PHP_EOL;
echo '<textarea name="message">' . e($old['message']) . '</textarea>' . PHP_EOL;
// Prints:
// <input name="email" value="ada@example.com">
// <textarea name="message">Hello &lt;team&gt;</textarea>
Escaping matters because submitted form values are user input. If you print them into HTML without escaping, a malicious value can become executable markup or script.
Reading a submitted form
In plain PHP, check the request method before treating a request as a submission:
<?php
declare(strict_types=1);
$server = ['REQUEST_METHOD' => 'POST'];
$post = ['email' => ' ada@example.com ', 'message' => ' Hello '];
if (($server['REQUEST_METHOD'] ?? 'GET') === 'POST') {
$email = trim((string) ($post['email'] ?? ''));
$message = trim((string) ($post['message'] ?? ''));
echo $email . ' sent: ' . $message . PHP_EOL;
}
// Prints:
// ada@example.com sent: Hello
This example uses arrays so it runs from the command line. In a real request, $server would be $_SERVER and $post would be $_POST.
File upload forms
File upload forms need enctype="multipart/form-data":
<form method="post" action="/avatar" enctype="multipart/form-data">
<label for="avatar">Avatar</label>
<input id="avatar" name="avatar" type="file">
<button type="submit">Upload</button>
</form>
Without the correct encoding type, uploaded files will not arrive in $_FILES as expected.
Common form mistakes
- Missing
nameattributes, so PHP receives no value. - Using
GETfor state-changing actions. - Not escaping old input when re-rendering the form.
- Trusting hidden inputs for prices, roles, permissions, or user IDs.
- Forgetting CSRF protection for state-changing browser forms.
- Not preserving user input after validation errors.
- Treating client-side validation as enough.
Browser validation and JavaScript can improve the user experience, but server-side validation is still required. A user can bypass the browser and send any request they want.
What you should be able to do
After this lesson, you should be able to build a basic HTML form, choose GET or POST, explain how input names become PHP values, preserve submitted values safely, and identify the security checks that belong around state-changing forms.
Practice
Task: Build A Contact Form Flow
Create a small PHP example that shows how a message form is rendered and how submitted values are read.
Requirements
- Include an HTML form with
method="post"andaction="/contact". - Include
emailandmessagefields with labels andnameattributes. - Show PHP reading submitted values from a request-style array.
- Trim the submitted values.
- Escape old values when rendering them back into the form.
- Include one normal submitted case and one empty submitted case.
- Add a short note explaining why server-side validation is still needed even when the HTML uses useful input types.
Check your work
The example should make the full form loop clear: render the form, receive submitted values, preserve safe old input, and prepare for validation.
Show solution
<?php
declare(strict_types=1);
function e(string $value): string
{
return htmlspecialchars($value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}
/**
* @return array{email: string, message: string}
*/
function readContactForm(array $post): array
{
return [
'email' => trim((string) ($post['email'] ?? '')),
'message' => trim((string) ($post['message'] ?? '')),
];
}
function renderContactForm(array $old): string
{
$email = e((string) ($old['email'] ?? ''));
$message = e((string) ($old['message'] ?? ''));
return <<<HTML
<form method="post" action="/contact">
<label for="email">Email</label>
<input id="email" name="email" type="email" value="{$email}">
<label for="message">Message</label>
<textarea id="message" name="message">{$message}</textarea>
<button type="submit">Send</button>
</form>
HTML;
}
$examples = [
['email' => ' ada@example.com ', 'message' => ' Hello team '],
['email' => '', 'message' => ''],
];
foreach ($examples as $example) {
$old = readContactForm($example);
echo $old['email'] . ' | ' . $old['message'] . PHP_EOL;
}
echo renderContactForm(['email' => 'ada@example.com', 'message' => 'Hello <team>']) . PHP_EOL;
// Output starts:
// ada@example.com | Hello team
// |
// <form method="post" action="/contact">
The HTML type="email" helps the browser give a better user experience, but it is not security. Server-side code still needs to validate that the email is present, has an acceptable shape, the message is present, and the request is allowed to perform the action.