Theory
Logged in, then a stranger again
A student logs into the event portal. They click to the events page and: the portal has no idea who they are. Log in again, click again, forgotten again.
This is not a bug in your code; it is how the web WORKS. HTTP is stateless: every request is independent, and the server remembers nothing between them by default. To keep someone logged in, you must add memory yourself. PHP gives you 2 tools, cookies and sessions, and choosing correctly between them is a security decision this lesson makes clear.
At a glance
Cookies vs sessions (the exam contrast)
| Aspect | Cookie | Session |
|---|---|---|
| Stored where | In the BROWSER (client) | On the SERVER |
| User can see/edit? | Yes: visible, editable | No: only a session ID cookie is exposed |
| Security | Lower: never store sensitive data | Higher: data stays server-side |
| Lifetime | Until its expiry (can persist for days) | Until logout or timeout |
| Good for | Remembering preferences, 'remember me' | Login state, cart, private data |
Theory
How each one works
Cookies are small pieces of data stored IN THE BROWSER and sent back with every request. Set one with setcookie("theme", "dark", time() + 86400); (expires in 1 day) and read it via $_COOKIE["theme"]. Because the user can see and edit cookies, never store sensitive data in them.
Sessions store data ON THE SERVER, keyed by a session ID that PHP keeps in a cookie. Call session_start() at the TOP of every page that uses the session (before ANY output), then read/write $_SESSION["user"]. The actual data never leaves the server, so login state belongs here. End it with session_destroy() on logout.
Practical
Login stored in a session, checked on another page
<?php
// login.php (after validating credentials)
session_start(); // before any output
$_SESSION["user"] = "Riya"; // stored on the SERVER
// Send a confirmation email
$to = "riya@example.com";
$subject = "Registration confirmed";
$message = "Welcome to the Event Portal, Riya!";
$headers = "From: portal@example.com\r\n";
mail($to, $subject, $message, $headers);
?>
<?php
// events.php (a different page)
session_start();
if (isset($_SESSION["user"])) {
echo "Welcome back, " . $_SESSION["user"]; // Welcome back, Riya
} else {
echo "Please log in";
}
?>
Theory
Sending email with mail()
The portal confirms a registration by email. PHP's basic tool is:
mail($to, $subject, $message, $headers);
The $headers string sets extras: From:, and Content-Type: text/html if you want an HTML email. One honest caveat the exam may not stress but reality does: mail() needs a properly configured mail server to actually deliver, which is why production apps usually use a library and SMTP (as the Grishu platform itself does). For this syllabus, know the mail() signature and what each argument does: recipient, subject, body, headers.
Quiz
Where should the portal store the fact that a user is logged in: a cookie or a session, and why?
- A cookie, because it is stored in the browser and faster
- A session, because login state is sensitive and sessions keep data on the SERVER where the user cannot see or edit it
- Either is equally secure
- Neither: HTTP remembers logins automatically
Show the answer
A session, because login state is sensitive and sessions keep data on the SERVER where the user cannot see or edit it
Login state is sensitive, so it belongs in a SESSION, which stores the data on the SERVER; only a session ID travels in a cookie, and the user cannot read or tamper with the actual login data. A COOKIE stores its data in the browser where the user can view and EDIT it, so putting 'logged_in = true' in a raw cookie would let anyone fake being logged in: a serious hole. Option A prioritises the wrong thing (speed over security). Option C ignores where each stores data. Option D is false: HTTP is stateless and remembers nothing. Rule: sessions for private state (logins), cookies for non-sensitive preferences.
Think first
The headers-already-sent error
A student calls session_start() after already echoing some HTML, and gets a 'headers already sent' warning. Why must session_start() come first? Then tap.
Show the answer
session_start() (like setcookie and other header operations) sends an HTTP HEADER: the session ID cookie: and HTTP requires ALL headers to be sent BEFORE any body content (the HTML). Once you echo even one character, PHP has begun the body and flushed the headers, so a later session_start() cannot add its header, hence 'headers already sent'. The fix: call session_start() at the very TOP of the page, before any echo, any HTML, even any stray whitespace before <?php. This ordering rule (headers before output) is one of the most common PHP errors and a frequent exam point. Put session_start() first, always.
Watch out
State and email traps
Sensitive data in cookies: users can read/edit cookies; login state goes in a SESSION.
session_start() after output: it must come before ANY output (even whitespace before <?php), or 'headers already sent'.
Forgetting session_start() on a page: $_SESSION is empty on pages that do not start the session.
Trusting mail() to always deliver: it needs a configured mail server; production uses SMTP libraries.
Not calling session_destroy() on logout: leaves the session alive.
Theory
The portal has memory; now structure
With sessions, the portal keeps you logged in across pages and emails your confirmation: it finally feels like a real application. One Unit 2 lesson remains: giving the code proper STRUCTURE with PHP's object-oriented features (classes, inheritance, visibility) and robust error handling with try/catch/finally, plus regex validation. Then Unit 3 connects the portal to a real MySQL database. Memory added; organisation next.
Summary
Key takeaways
- HTTP is stateless: the server forgets you between requests, so you must add memory.
- Cookies store data in the BROWSER (visible/editable by the user): use only for non-sensitive data; set with setcookie, read via $_COOKIE.
- Sessions store data on the SERVER (keyed by a session ID cookie): call session_start() before any output, use $_SESSION.
- Login state is sensitive: store it in a SESSION, never a raw cookie.
- session_start() (and setcookie) send headers, so they must come before ANY output ('headers already sent' otherwise).
- mail($to, $subject, $message, $headers) sends email; real delivery needs a configured mail server/SMTP.
- Memory hook: cookie in the browser, session on the server, session_start() first.