2.1 · Forms & superglobals ($_GET, $_POST)

Level 2 · PHP & the Web

2.1Forms & superglobals ($_GET, $_POST)

Goal: Receive form data via $_GET/$_POST and process it correctly (systematic server-side validation and sanitization) — the heart of web interaction and the first line of defence.
Estimated time: 12 min · self-paced reading · If you only have 5 min: read “The essentials in 30s” + the diagram.

The essentials in 30 seconds

  • GET reads, POST changes: GET exposes data in the URL (search, filters, shareable links); POST sends it in the body (registration, login, sensitive data) — never put a password in GET.
  • Never trust user input: any received data is potentially wrong or malicious — server-side validation is mandatory; JavaScript validation is never enough.
  • Validate first, then sanitize for the context: filter_var checks the format, htmlspecialchars protects output, prepared statements protect the database — one tool per use.

Running mini-case — Riad and the registration form in Constantine

Riad, a web developer in Constantine, builds the registration form of a local association: name, email, wilaya. His first version displays exactly what the user types — a test with a script in the name field breaks the page. He rebuilds the handling in three steps: collect via $_POST, validate on the server (required field, valid email with filter_var), escape with htmlspecialchars before any output. This same project returns in 2.2 (keeping the user logged in with a session), 2.3 (factoring the form out with includes) and 2.4 (validating the email and dating the registration).

Thread of level 2: this same Riad project returns in the lesson, the diagram, the script and the 48h challenge — and continues in 2.2, 2.3 and 2.4.

1. $_GET and $_POST: two methods, two uses

A web application INTERACTS with the user, mostly through forms. When the form is submitted, the data travels to the server and PHP COLLECTS it using superglobals — special arrays available everywhere in the code. The GET method puts the data in the URL (the “query string”: recherche.php?q=chaise): it is VISIBLE, stored in history, shareable and bookmarkable — ideal for READING (search, filter, pagination, sorting), because the request is idempotent (reloading it changes nothing). PHP reads it in $_GET ($_GET['q']). The POST method puts the data in the BODY of the request (invisible in the URL): ideal for CREATING/MODIFYING (registration, login, orders) and for sensitive or bulky data. PHP reads it in $_POST. The HTML form declares the method (method='post') and the target (action: the PHP file that processes it). Riad applies this: his member search goes via GET (shareable URL), his registration goes via POST. Other superglobals exist: $_FILES (uploads, section 2.3), $_SERVER (request info), $_SESSION/$_COOKIE (section 2.2). Avoid: $_REQUEST, which mixes GET and POST and lacks precision.

2. Never trust user input

The core reflex of the web developer: NEVER trust received data. Anything coming from the client (form, URL, header) is potentially WRONG or MALICIOUS: a user can disable JavaScript, edit the code in their browser, or send forged requests straight to the server without ever going through your page. Client-side validation (JavaScript) serves the EXPERIENCE (instant feedback, guidance) but it is bypassable; server-side validation (PHP) serves SECURITY and it is mandatory — it is the only one you control. Riad learned this the hard way: his JavaScript “required field” check blocked nothing when a tester submitted the empty form with a direct tool. Rule: re-check EVERYTHING on the server, always.

3. Validate, then sanitize for the context

Server-side handling comes down to two actions. Validate: check that the data has the expected format (required field filled in? valid email? positive number?) and reject/report otherwise — PHP helps with filter_var() (email, URL, integer…). Sanitize/escape: process the data according to how it is used — htmlspecialchars() before DISPLAYING (against XSS, which injects HTML/JavaScript into your pages), prepared statements before putting it in the DATABASE (against SQL injection, level 3). One tool per context, never the reverse. So Riad's form validates the email with filter_var($email, FILTER_VALIDATE_EMAIL) then displays the name with htmlspecialchars($nom) — systematically, with no exception.

Common misinterpretation: “My JavaScript already checks everything, so PHP validation is redundant.” No. The browser belongs to the user, not to you: disabled JavaScript, code edited via the developer tools, or a forged request sent directly to the server — in all three cases your client-side validation simply does not exist. Keeping only client-side checks leaves the door open to invalid data, data corruption and vulnerabilities (XSS, SQL injection). Riad's rule: client side for comfort (desirable), server side for security (imperative) — re-check everything on the server, every time.
Processing form data Receive, validate, sanitize Form GET (URL) orPOST (body)Collect $_GET / $_POSTon the serverValidate Expectedformat (filter_var)Sanitize htmlspecialchars,prepared statements
Receive, validate, sanitize
Text version of the diagram (SEO / screen readers / translation): 1) Riad's FORM sends the data: his search goes via GET (shareable URL), his registration via POST (body, not visible). 2) He COLLECTS it on the server with $_GET / $_POST — never $_REQUEST. 3) He VALIDATES: required field, valid email via filter_var, otherwise reject. 4) He SANITIZES for the use: htmlspecialchars before displaying (anti-XSS), prepared statement before the database. Lesson: receive, validate, sanitize — always on the server, because the client can be bypassed.

🔎 Concrete example — 🔎 Concrete example — Riad's registration, validated on the server

The first line of defence, as in Riad's form:

$nom = trim($_POST['nom'] ?? '');
$email = trim($_POST['email'] ?? '');
if ($nom === '' || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
  echo 'Invalid registration.';
} else {
  echo 'Thank you ' . htmlspecialchars($nom, ENT_QUOTES, 'UTF-8') . ' !';
}

Reading: collected via $_POST, format validated, escaped before display.

Lesson: JavaScript validation is NEVER enough — the server re-checks everything.

Section vocabulary

Forms / superglobals
Forms send data to the server, which PHP collects via superglobals, special arrays available everywhere: $_GET, $_POST, $_FILES, $_SESSION…

Simple example: Riad reads the entered name with $_POST['nom'].

What it is not: ordinary variables limited to one function.

Reflex: data from the client = superglobal + suspicion.

$_GET vs $_POST
GET: data in the URL, visible and shareable, for reading (search, filters). POST: data in the body, not visible in the URL, for modifying or for sensitive data.

Simple example: Riad's search goes via GET, his registration via POST.

What it is not: two interchangeable syntaxes with no consequences.

Reflex: reading = GET; modifying or sensitive = POST.

Never trust user input
Any user data is potentially wrong or malicious; always validate and sanitize on the SERVER before using it.

Simple example: Riad re-checks the email on the server even with a JavaScript check.

What it is not: data displayed as-is because it comes from his own form.

Reflex: received input = suspicious input until validated.

Validate
Check that data has the expected format (required filled in, valid email, correct number) and reject otherwise; filter_var() helps for email, URL, integer.

Simple example: filter_var($email, FILTER_VALIDATE_EMAIL) accepts or rejects the registration.

What it is not: displaying the data and hoping it is correct.

Reflex: each field = one explicit validation rule.

Mandatory server-side validation
Client-side (JavaScript) validation improves the experience but can be bypassed; server-side (PHP) validation is mandatory because it is the only reliable one.

Simple example: Riad's tester bypasses the JavaScript, yet the PHP still blocks.

What it is not: a JavaScript check treated as protection.

Reflex: comfort on the client, security on the server.

In practice — In practice — Receiving and processing form data

  1. Create an HTML form (method='post', action pointing to a PHP file) and collect the data on the server via $_POST['champ'].
  2. Compare GET and POST: a search form in GET (data in the URL) vs a registration form in POST (body, not visible).
  3. VALIDATE the data on the server: required field filled in? valid email (filter_var)? correct number? — reject/report if invalid.
  4. SANITIZE: escape with htmlspecialchars() before displaying user data — and remember that client-side (JS) validation is NEVER enough.
You receive form data via $_GET/$_POST and process it correctly (systematic server-side validation and sanitization) — the heart of web interaction and the first line of defence.

Ready-to-say script — explaining double validation to a colleague (30 s)

“For the registration form, I keep the JavaScript check for comfort — instant feedback. But I re-check everything in PHP: required field, email with filter_var, and htmlspecialchars before displaying. JavaScript is bypassed in two clicks; PHP is the only place I really control.”

Say it while showing a forged request that bypasses the JavaScript but gets blocked by the PHP.

Copy-paste template — safe form handling

' . htmlspecialchars($e, ENT_QUOTES, 'UTF-8') . '

'; } return; } echo '

Thank you ' . htmlspecialchars($nom, ENT_QUOTES, 'UTF-8') . ' (' . htmlspecialchars($email, ENT_QUOTES, 'UTF-8') . ') !

';

Shareable search

Riad's catalogue is filtered via GET: the URL holds the criteria, so it can be shared and bookmarked.

Sensitive registration

Name, email and password go via POST: nothing in the URL, nothing in the history — then HTTPS for transport.

Allowlist of values

The wilaya comes from a closed list: Riad checks that the received value belongs to the allowed choices, otherwise reject.

Bulky form

Long message, several fields: POST accepts more data than GET, which is limited by URL length.

Caution: Displaying any user data without htmlspecialchars() opens an XSS hole: an attacker injects HTML or JavaScript that runs in visitors' browsers (session theft, defacement). Systematically escape every displayed data item, with no exception. This guide gives the basic action — for sensitive contexts, have your code reviewed by an experienced developer.

✓ Best practices

  • GET for reading (search, filter); POST for modifying or for sensitive data.
  • Always validate on the server (filter_var, explicit checks).
  • Escape with htmlspecialchars before displaying any user data.

✗ Common pitfalls

  • Relying on JavaScript validation (bypassable in two clicks).
  • Passing a password via GET (visible in the URL, history and logs).
  • Using $_REQUEST (mixes GET/POST, less precise and less safe).

Key takeaways

  • FORMS send data that PHP collects via SUPERGLOBALS: $_GET (URL, searches/filters) and $_POST (body, forms that modify/sensitive data).
  • CORE REFLEX: NEVER trust user data (potentially wrong or malicious) — always VALIDATE and SANITIZE on the SERVER before use.
  • VALIDATE (expected format: email, number, required — filter_var) and SANITIZE/ESCAPE for the context (htmlspecialchars before displaying, prepared statements before the database).
  • CLIENT-SIDE (JavaScript) validation improves the experience but can be BYPASSED; SERVER-SIDE (PHP) validation is MANDATORY — it is what really protects.

48h challenge — apply it tomorrow

Take a real form (yours or Riad's: name + email) and add the complete server-side handling: collection via $_POST, validation (required + filter_var), display with systematic htmlspecialchars. Then bypass your own JavaScript and check that the PHP blocks it.

Section exit checklist
  • I can explain when to use GET and when to use POST, with one example of each.
  • I can validate on the server (required, filter_var) and escape before display.
  • I have tested that a forged request does not pass my server-side handling.
Self-rating 1-5: do I always validate on the server?do I escape every displayed data item with htmlspecialchars?

Frequently asked questions

GET or POST: how do I choose the right method for a form?

Depends on the nature of the action and the sensitivity of the data. GET: data appended to the URL (visible, stored in history, shareable, bookmarkable). POST: data in the body (not in the URL). Rule: use GET to READ/RETRIEVE (search, filter, pagination, sorting, links) — the request is idempotent (safe to reload) and the URL is shareable. Use POST to CREATE/MODIFY/DELETE (registration, login, submission, orders) — these actions must not repeat by accident on reload (the browser warns before resending POST data), the data does not pollute the URL, and POST accepts more data. SENSITIVE data (passwords) → POST, never GET — but POST alone encrypts nothing: you need HTTPS for real confidentiality (POST avoids exposure in the URL, HTTPS protects transport). HTML forms natively support only GET and POST; APIs (section 4-4) also use PUT/PATCH/DELETE.

Why is server-side validation mandatory if I already validate on the client (JavaScript)?

Because the client is NOT trustworthy. CLIENT-side validation (JavaScript) serves the EXPERIENCE: instant feedback, guidance — useful but easily BYPASSABLE: disabled JavaScript (validation skipped), code edited via the browser tools, or a request sent DIRECTLY to the server (tool or script) without ever going through your page. Nothing guarantees that a received request comes from your form. SERVER-side (PHP) validation serves SECURITY: it is the only reliable place, the one YOU control. Without it: corrupted data, bugs, and VULNERABILITIES (SQL injection, XSS). Do both: client side for comfort (desirable), server side for security (imperative) — re-check EVERYTHING (required, formats, lengths, allowed values) and sanitize for the use. Picture it: client-side validation is a polite sign, server-side validation is the real check.

Check your understanding

Is client-side (JavaScript) validation enough for security?

Additional resources (optional, to go further)

Level 2 examFresh, harder questions to test what you've learned