PHP Forms

A basic form

HTML
<form method="post" action="submit.php">
    <label>Name: <input type="text" name="name"></label>
    <label>Email: <input type="email" name="email"></label>
    <button type="submit">Send</button>
</form>

Reading it in PHP

PHP
<?php
// submit.php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $name  = trim($_POST['name']  ?? '');
    $email = trim($_POST['email'] ?? '');

    echo "Thanks, " . htmlspecialchars($name);
}

The name attribute in the HTML is the key in $_POST. No name, no data.

GET vs POST

GET POST
Data location URL query string request body
Visible in address bar yes no
Bookmarkable yes no
Size limit ~2000 chars effectively unlimited
Use for searches, filters, pagination logins, orders, anything that changes data

Rule of thumb: GET reads, POST writes. Never delete or charge anything from a GET request — browsers and crawlers prefetch GET URLs.

Self-submitting form

PHP
<?php
$errors = [];
$name = '';

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $name = trim($_POST['name'] ?? '');
    if ($name === '') {
        $errors[] = 'Name is required.';
    }
    if (!$errors) {
        // save, then redirect (see below)
    }
}
?>
<form method="post">
    <input type="text" name="name" value="<?= htmlspecialchars($name) ?>">
    <button>Submit</button>
</form>
<?php foreach ($errors as $e): ?>
    <p style="color:red"><?= htmlspecialchars($e) ?></p>
<?php endforeach; ?>

Re-filling the input with the submitted value (value="...") is what makes a failed submission not feel broken.

Post/Redirect/Get

After a successful POST, redirect instead of rendering directly. This stops the browser from re-submitting the form when the user hits refresh:

PHP
<?php
  // ... save the record ...
  header('Location: /thank-you.php');
  exit;   // always exit after a redirect

File uploads

HTML
<form method="post" enctype="multipart/form-data">
    <input type="file" name="photo">
    <button>Upload</button>
</form>
PHP
<?php
if (isset($_FILES['photo']) && $_FILES['photo']['error'] === UPLOAD_ERR_OK) {
    $tmp  = $_FILES['photo']['tmp_name'];
    $name = basename($_FILES['photo']['name']); // basename() strips paths
    move_uploaded_file($tmp, __DIR__ . "/uploads/" . $name);
}

enctype="multipart/form-data" is required or $_FILES stays empty. Always validate the file's real type and size — never trust the browser-supplied name or MIME type.