PHPForm Handling

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

HTML
<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
<?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
<?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;
}
Call exit after header('Location: ...')
`header()` sends the redirect response header, but PHP keeps executing the rest of the script unless you stop it. Always follow a redirecting `header()` call with `exit;` so no further output or processing happens after the redirect has been issued.
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().

Do not skip validation because a field 'looks' filled in
`trim($_POST['name'] ?? '')` only guarantees you have a string, not that it is a sensible name. Combining form handling with the validation techniques on the next page is what actually protects your application, not the act of reading `$_POST` by itself.
Tip
Keep the "read from $_POST" step and the "do something with the data" step separate functions or sections. It makes the same form logic easy to reuse if you ever need to accept the same data from an API endpoint instead of an HTML form.