💡 TL;DR
A broken PHP form almost always comes down to one of five things: wrong method attribute, a mismatched name on your input, checking $_POST with the wrong key, a form that isn't actually submitting, or output sent before a header() redirect. Fix those five and "PHP POST not working" stops being a mystery.
You hit submit. Nothing happens. Or worse — the page reloads and $_POST is just... empty. You var_dump() it, get array(0) { }, and start questioning every life choice that led you here.
Here's the direct answer: it's not really a "PHP bug." Nine times out of ten it's a small disconnect between your HTML form tag and the script reading it.
How PHP Actually Reads Form Data
When a form submits, PHP populates $_POST (for method="post") or $_GET (for method="get") using the input's name attribute — not the id, not the label text.
<form action="process.php" method="post">
<input type="text" name="user_email" id="emailField">
<button type="submit">Submit</button>
</form>
<?php
// process.php
if (isset($_POST['user_email'])) {
$email = $_POST['user_email'];
echo "Received: " . htmlspecialchars($email);
} else {
echo "No email field received.";
}
$_POST['user_email'] matches name="user_email" — not id="emailField". This mismatch is the #1 source of form bugs, and it's the first thing to check when $_POST comes back empty.
If you haven't already, it's worth skimming our PHP Developer Roadmap 2026 — form handling is one of those "basics" that keeps showing up at every level.
5 Common PHP Form Bugs
Bug 1: $_POST Array Is Empty
Your form's method is set to get, or missing entirely (which silently defaults to get in HTML).
<!-- Wrong — defaults to GET -->
<form action="process.php">
<input type="text" name="username">
</form>
<!-- Fixed -->
<form action="process.php" method="post">
<input type="text" name="username">
</form>
Pro tip while debugging: use $_REQUEST temporarily — it merges GET, POST, and COOKIE, so you can confirm data is arriving at all before chasing the method.
Bug 2: isset($_POST['field']) Returns False
The field shows up in the Network tab, but isset() still says no. Classic case mismatch.
<?php
// Bad — HTML says name="userName", PHP checks "username"
if (isset($_POST['username'])) {
echo "Welcome, " . $_POST['username'];
}
// Fixed — exact match, including case
if (isset($_POST['userName'])) {
echo "Welcome, " . htmlspecialchars($_POST['userName']);
}
$_POST keys are case-sensitive strings. userName and username are two different keys. No error, just a silent false.
Bug 3: Checkboxes Never Show Up in $_POST
This one isn't a PHP quirk at all — it's how HTML has always worked. Unchecked checkboxes send nothing.
<form action="process.php" method="post">
<label>
<input type="checkbox" name="subscribe" value="yes"> Subscribe
</label>
<button type="submit">Submit</button>
</form>
<?php
// Bug: assumes the key always exists
$subscribed = $_POST['subscribe'];
// Notice: Undefined array key "subscribe" if unchecked
// Fixed: always check first
$subscribed = isset($_POST['subscribe']) ? $_POST['subscribe'] : 'no';
echo "Subscription status: " . htmlspecialchars($subscribed);
Your PHP has to plan for that key not existing — it's not a bug, it's just how forms work.
Bug 4: Form Submits, Page Reloads, Nothing Happens
Either the action attribute points to the wrong file (or is missing), or your handler has no visible output.
<!-- Fixed -->
<form action="submit_feedback.php" method="post">
<input type="text" name="feedback">
<button type="submit">Send</button>
</form>
<?php
// submit_feedback.php
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['feedback'])) {
$feedback = trim($_POST['feedback']);
echo $feedback !== '' ? "Thanks for your feedback!" : "Feedback cannot be empty.";
}
I've seen this in production more than once — someone copies a form snippet from an old project and forgets to update the action path. It "submits," just to the wrong endpoint.
Bug 5: "Headers Already Sent" Error
You call header('Location: thankyou.php') after processing, and PHP throws a warning because something — whitespace, an HTML tag, an echo — already sent output.
<?php
// Fixed — process logic and redirect BEFORE any HTML output
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['submit'])) {
// ...validate and save...
header('Location: thankyou.php');
exit; // always exit after a redirect
}
?>
<!DOCTYPE html>
<html>
<!-- form HTML goes here -->
</html>
header() calls belong at the very top of your script's execution, before a single character of HTML gets echoed out.
2-Minute Diagnostic Checklist
- Is
method="post"actually on the<form>tag? - Do your
nameattributes exactly match your$_POSTkeys, case included? - Does
actionpoint to the correct file? - Does
var_dump($_SERVER['REQUEST_METHOD']);confirm the request arrived as POST? - Is there any whitespace or HTML output before a
header()call?
GET vs POST, Quickly
| Feature | GET | POST |
|---|---|---|
| Visibility | In the URL | In the request body |
| Size limit | ~2048 chars | No practical limit |
| Use case | Search, filters | Login, uploads, sensitive data |
| Caching | Cacheable | Not cached by default |
Wrapping Up
A broken PHP form is rarely a "PHP mystery" — it's usually a small mismatch between your HTML and your script. Run through the five bugs above in order and you'll catch it in minutes instead of hours.
For more real-world PHP debugging, check out 10 Common PHP Bugs in Real-Time Development, the follow-up PHP Bugs 21 to 30, and if you're newer to the language, Top 10 PHP Bugs Every Beginner Makes. If echo vs print still trips you up, we've got that covered too in Difference Between echo and print in PHP. And if you're prepping for interviews, don't miss Top 15 PHP Interview Questions Asked in 2026.
Want the full breakdown with the complete FAQ section and reference docs? Read the original, detailed post here: Why Your PHP Form Is Not Working — 5 Common Bugs Fixed
Found this helpful? Check out more at codepractice.in
Top comments (0)