Form Handling
Handling a form in plain PHP usually means one file doing two jobs: rendering the HTML form, and — when that same form is submitted — reading the submitted values and acting on them. This "self-submitting" pattern, where a form posts back to its own URL, is the simplest way to see the whole request/response cycle without a framework in the way.
A self-submitting form
Leaving the action attribute empty (or setting it to the current path) tells the browser to submit the form back to the same page. The PHP at the top of that page then decides whether it is handling a fresh page load or a submitted form, based on the request method.
A simple contact form
<form method="post" action=""> <label for="name">Name</label> <input type="text" id="name" name="name"> <label for="email">Email</label> <input type="email" id="email" name="email"> <label for="message">Message</label> <textarea id="message" name="message"></textarea> <button type="submit">Send</button> </form>
Checking the request method first
Before touching $_POST, check $_SERVER['REQUEST_METHOD']. On the first visit to the page the request is a GET, so $_POST will be empty and there is nothing to process yet — only the form should be shown. Only when the method is POST has the visitor actually submitted data.
Reading multiple fields on POST
<?php
$submitted = false;
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$name = trim($_POST['name'] ?? '');
$email = trim($_POST['email'] ?? '');
$message = trim($_POST['message'] ?? '');
$submitted = true;
}
?>
<?php if ($submitted): ?>
<p>
Thanks, <?= htmlspecialchars($name, ENT_QUOTES, 'UTF-8') ?>.
We received your message.
</p>
<?php endif; ?>Thanks, Aisha. We received your message.
The redirect-after-post pattern
If a successful form submission simply renders a "thank you" message on the same POST response, reloading that page (or pressing back and forward) resubmits the form and can duplicate the action — sending a second email, placing a second order. The fix is to redirect to a fresh URL after a successful POST, so the browser's last request in history is a GET rather than a POST.
Redirect after a successful submission
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$name = trim($_POST['name'] ?? '');
$email = trim($_POST['email'] ?? '');
$message = trim($_POST['message'] ?? '');
// ... save $name, $email, $message somewhere ...
header('Location: /contact-thanks.php');
exit;
}Putting it together
On a GET request, show the empty form.
On a POST request, read and trim each expected field with
$_POST[...] ?? ''.Validate the fields (see the Form Validation page) before doing anything with them.
On success, redirect to a different URL and exit immediately.
Escape any value you redisplay in HTML with
htmlspecialchars().