Forms & Superglobals
This is where PHP starts doing the job it was built for: reading data a visitor typed into a form. Superglobals are built-in associative arrays PHP fills in automatically on every request, and $_GET/$_POST are the two you'll use constantly.
A basic HTML form
An HTML form's action attribute says which PHP file receives the submission, and method says how — GET appends the data to the URL, POST sends it in the request body:
<form action="greet.php" method="post"> <input type="text" name="username"> <button type="submit">Say hi</button> </form>
Each input's name attribute becomes the key PHP will read the submitted value by — here, username.
Reading $_POST
<?php $name = $_POST["username"] ?? "stranger"; echo "Hello, " . htmlspecialchars($name) . "!"; ?>
Hello, Priya!
$_POST["username"] reads the submitted value by the input's name. The ?? fallback from the Conditionals lesson keeps this from erroring if the form was never actually submitted. htmlspecialchars() converts characters like < and > into their HTML-safe equivalents before the value gets echoed back into a page.
htmlspecialchars() here is a textbook cross-site scripting (XSS) hole — a visitor could submit <script>...</script> as their "username" and have it run in every other visitor's browser who views the output. Treat every value from $_GET, $_POST, and $_COOKIE as untrusted until you've escaped or validated it.$_GET and query strings
$_GET reads values appended to the URL after a ?, like page.php?id=42&sort=name:
<?php // visited as product.php?id=42&sort=name $id = $_GET["id"] ?? null; $sort = $_GET["sort"] ?? "default"; echo "Showing product $id, sorted by $sort"; ?>
Showing product 42, sorted by name
$_GET is well suited to values that make sense to see and bookmark in a URL, like a product ID or a search term. $_POST is preferred for anything sensitive, large, or that changes data — passwords should never travel through $_GET, since URLs end up in browser history and server logs.
Validating input
<?php $age = $_POST["age"] ?? ""; if (!is_numeric($age) || (int)$age < 0) { echo "Please enter a valid age."; } else { echo "Age accepted: " . (int)$age; } ?>
Please enter a valid age.
Every value coming out of a superglobal arrives as a string, even a form field that looks numeric — is_numeric() checks that it can be safely treated as a number before (int)$age converts it. Skipping this check and trusting the input directly is how malformed or malicious data ends up further into your application.