Forms and superglobals
Superglobals are built-in arrays that PHP fills in for every web request, available everywhere in your code.
| Superglobal | Holds |
|---|---|
$_GET | values from the URL's query string: page.php?q=php&page=2 |
$_POST | values from a form sent with method="post" |
$_SERVER | information about the request and server: method, path, headers |
$_COOKIE | cookies the browser sent |
$_SESSION | data stored for one visitor across requests, after session_start() |
$_FILES | uploaded files |
A form and its handler
<form action="register.php" method="post">
<input name="name">
<input name="email" type="email">
<input name="age" type="number">
<button>Register</button>
</form>When this form is submitted, register.php receives each field in $_POST, under the field's name.
Reading input safely
<?php
$_POST = ["name" => " Asha Verma ", "email" => "asha@example.com", "age" => "21"]; // pretend a form was sent
$name = trim($_POST["name"] ?? "");
$email = $_POST["email"] ?? "";
$age = $_POST["age"] ?? null;
$newsletter = isset($_POST["newsletter"]); // unchecked checkboxes aren't sent at all
var_dump($name, $email, $age, $newsletter);- Every value arrives as a string, even numbers:
"21", not21. - A field might be missing altogether, so read it with
?? defaultrather than directly. - A checkbox that isn't ticked is simply absent, so
issettells you whether it was ticked.
Validating
<?php
$_POST = ["email" => "not-an-email", "age" => "seventeen", "website" => "https://example.com"];
$errors = [];
$email = filter_var($_POST["email"] ?? "", FILTER_VALIDATE_EMAIL);
if ($email === false) $errors[] = "Please enter a valid email address.";
$age = filter_var($_POST["age"] ?? "", FILTER_VALIDATE_INT, ["options" => ["min_range" => 13, "max_range" => 120]]);
if ($age === false) $errors[] = "Age must be a whole number from 13 to 120.";
$site = filter_var($_POST["website"] ?? "", FILTER_VALIDATE_URL);
print_r($errors);
var_dump($site);filter_var returns the cleaned value, or false when it's invalid. Never trust anything a browser sends: validate every field on the server, even if the form already checks it with HTML attributes, because anyone can send a request without your form.
Escaping output: stopping XSS
<?php
$_GET = ["q" => '<script>alert("hacked")</script>'];
$q = $_GET["q"] ?? "";
echo "Unsafe: You searched for $q\n";
echo "Safe: You searched for " . htmlspecialchars($q) . "\n";Printing user input straight into a page lets anyone inject their own HTML and JavaScript. That's cross-site scripting (XSS), one of the most common security holes on the web. htmlspecialchars turns <, >, & and quotes into harmless entities. Escape every piece of user-supplied text when you output it.
GET or POST?
- GET: the data goes in the URL. Use it for searches and filters, which are safe to bookmark, share and repeat.
- POST: the data goes in the request body. Use it for anything that changes something (sign-ups, orders, deletions) and for anything private, like passwords.
After a successful POST, redirect, with header("Location: /thanks.php"); exit;, so that refreshing the page doesn't send the form a second time. This is the Post/Redirect/Get pattern.
The request itself: $_SERVER
$method = $_SERVER["REQUEST_METHOD"]; // "GET" or "POST"
$path = $_SERVER["REQUEST_URI"]; // "/courses.php?page=2"
if ($method === "POST") {
// handle the submitted form
}Sessions
session_start(); // before any output
$_SESSION["user_id"] = 42; // after a successful login
// on any later page, after session_start():
$userId = $_SESSION["user_id"] ?? null; // null means "not logged in"A session keeps data for one visitor across page loads. PHP stores the data on the server and gives the browser a cookie with a random session id. It's how a site remembers who's logged in.