State Management 8 programs with output 15 Q/A 5 MCQs

Learning Objectives – after this chapter you will be able to:

  • Explain how PHP sessions work and how they relate to cookies.
  • Start a session and store, read and remove session variables with $_SESSION.
  • Build a page-view counter, a login/logout system and a shopping cart with sessions.
  • Save session data to a file with session_encode() and restore it with session_decode().
  • List the advantages and disadvantages of session state and the main security practices.
Session State

In PHP, session state stores user-specific information for a web site on the server. The scope of session state is limited to the current browser session: if different users access a web application, each has a different session; if a user leaves the application and returns later (after the session has expired), he or she gets a new session.

Session state is structured as key–value pairs that are kept between server round trips and between requests for pages.

Sessions and cookies

Sessions and cookies serve somewhat the same purpose and are, to a certain extent, interchangeable. Sessions – integrated into PHP in version 4 – are a means to store and track data for a user while he or she travels through a series of pages on your site. The most important differences:

AspectCookieSession
Stored onthe client (browser)the server (a session file in XAMPP's tmp folder)
Securityvisible and changeable by the userdata is not sent to the client – only a random id
Sizeabout 4 KB per cookielimited only by server resources
Lifetimeuntil it expires – can last for monthsuntil the browser closes or the session times out
Disabled cookiesdo not workthe id can be passed in the URL (if configured)
How Sessions Work

A session is started with the session_start() function. Like setcookie(), session_start() must come before any HTML output, including blank lines:

<?php
session_start();
?>
<html>
<head> ....... etc

session_start() generates a random session id and stores it in a cookie on the user's computer – this is the only session information kept on the client. The default name of this cookie is PHPSESSID (configurable with session.name in php.ini or session_name()). The data itself is stored on the server in a file named after the id (in XAMPP: C:\xampp\tmp\sess_<id>).

On the next request the browser sends the PHPSESSID cookie back; when the script calls session_start() again, PHP sees that a session is already in progress and resumes it, loading its data into $_SESSION.

1. First request session_start() creates a new id, e.g. k4v2…, and sends Set-Cookie: PHPSESSID=k4v2….
↓
2. Script Stores data: $_SESSION['user'] = 'Asha'; – saved on the server in sess_k4v2….
↓
3. Next request The browser sends Cookie: PHPSESSID=k4v2…; session_start() loads the data into $_SESSION.
↓
4. End session_destroy() (logout) or the session expires after session.gc_maxlifetime seconds of inactivity (default 1440 = 24 minutes).

Figure 31.1 – Life of a PHP session

Starting a Session and Storing Variables

Before you can store user information in a PHP session, you must start the session. Note: session_start() must appear before the <html> tag.

File: htdocs/phpbook/ch31/start.php
<?php session_start(); ?>
<html>
<body>
Session started. Your session id is <?= session_id() ?>
</body>
</html>
OUTPUT browser · http://localhost/phpbook/ch31/start.php
Session started. Your session id is o420qurmeck9av4eujiqu5eaqf

The correct way to store and retrieve session variables is the superglobal $_SESSION array:

File: htdocs/phpbook/ch31/store.php
<?php
session_start();
// store session data
$_SESSION['views'] = 1;
?>
<html>
<body>
<?php
// retrieve session data
echo "Pageviews=" . $_SESSION['views'];
?>
</body>
</html>
OUTPUT browser · http://localhost/phpbook/ch31/store.php
Pageviews=1

PHP 5.4 change. Old notes register session variables with session_register("username") and then use $username, and print the id with $PHPSESSID. These relied on register_globals; session_register(), session_unregister() and session_is_registered() were removed in PHP 5.4. Always use $_SESSION['username'] and session_id().

A session variable set on one page is available on every other page of the session:

File: htdocs/phpbook/ch31/page_b.php
<?php
session_start();
echo "Your name is: " . ($_SESSION['username'] ?? "unknown") . "<br>";
echo "Your city is: " . ($_SESSION['city'] ?? "unknown") . "<br>";
echo "Session id: " . session_id();
?>
OUTPUT browser · page_b.php after visiting page_a.php
Your name is: Goody
Your city is: Bhopal
Session id: o420qurmeck9av4eujiqu5eaqf
A Page-Views Counter

The isset() function checks whether the "views" variable has already been set. If it has, we increment the counter; if not, we create it and set it to 1:

File: htdocs/phpbook/ch31/counter.php
<?php
session_start();
if (isset($_SESSION['views']))
    $_SESSION['views'] = $_SESSION['views'] + 1;
else
    $_SESSION['views'] = 1;
echo "Views=" . $_SESSION['views'];
?>
OUTPUT browser · counter.php after the fourth refresh
Views=4
Destroying a Session

To delete some session data, use unset(); to delete everything, use session_unset() and session_destroy().

<?php
unset($_SESSION['views']);      // frees one session variable
?>
File: htdocs/phpbook/ch31/logout_demo.php
<?php
session_start();
$_SESSION = [];                 // empty the array
session_destroy();              // delete the session data on the server
setcookie(session_name(), "", time() - 3600, "/");   // delete the session cookie
echo "Session destroyed.";
?>
OUTPUT browser · counter.php opened again after logout_demo.php
Views=1

Note: session_destroy() resets your session and you lose all stored session data – the counter starts again at 1.

Example – Login and Logout with Sessions

A typical use of sessions is to remember that a user has logged in. (In Part IV the users come from a database; here they are in an array.)

File: htdocs/phpbook/ch31/login.php
<?php
session_start();
$users = ["asha" => password_hash("asha123", PASSWORD_DEFAULT)];   // demo user
$error = "";
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $u = $_POST["user"] ?? "";
    $p = $_POST["pass"] ?? "";
    if (isset($users[$u]) && password_verify($p, $users[$u])) {
        session_regenerate_id(true);          // new id after login
        $_SESSION["user"] = $u;
        $_SESSION["login_time"] = date("H:i");
        header("Location: dashboard.php");
        exit;
    }
    $error = "Invalid user name or password";
}
?>
<html><body style="font-family:Arial;font-size:13px">
<h3>Login</h3>
<span style="color:#c00"><?= $error ?></span>
<form method="post">
  User: <input name="user" id="u"> Password: <input type="password" name="pass" id="p">
  <input type="submit" value="Login" id="b">
</form>
</body></html>
File: htdocs/phpbook/ch31/dashboard.php
<?php
session_start();
if (!isset($_SESSION["user"])) {          // protect the page
    header("Location: login.php");
    exit;
}
?>
<html><body style="font-family:Arial;font-size:13px">
<h3>Dashboard</h3>
Welcome <b><?= htmlspecialchars($_SESSION["user"]) ?></b>, you logged in at <?= $_SESSION["login_time"] ?>.
<a href="logout.php" id="out">Logout</a>
</body></html>
File: htdocs/phpbook/ch31/logout.php
<?php
session_start();
session_unset();
session_destroy();
header("Location: login.php");
exit;

Opening dashboard.php without logging in sends the user to the login page; a wrong password shows the error:

OUTPUT browser · dashboard.php → redirected to login.php, then a wrong password
Browser output

With the correct password the user reaches the dashboard:

OUTPUT browser · login.php with the correct password → dashboard.php
Browser output
Example – A Shopping Cart
File: htdocs/phpbook/ch31/cart.php
<?php
session_start();
$prices = ["Pen" => 20, "Notebook" => 60, "Bag" => 850];
$_SESSION["cart"] ??= [];
if (isset($_GET["add"]) && isset($prices[$_GET["add"]])) {
    $item = $_GET["add"];
    $_SESSION["cart"][$item] = ($_SESSION["cart"][$item] ?? 0) + 1;
}
if (isset($_GET["remove"])) {
    unset($_SESSION["cart"][$_GET["remove"]]);
}
$total = 0;
echo "<b>Your cart</b><br>";
foreach ($_SESSION["cart"] as $item => $qty) {
    $amount = $qty * $prices[$item];
    $total += $amount;
    echo "$item x $qty = Rs. $amount<br>";
}
echo "<b>Total: Rs. $total</b>";
?>
OUTPUT browser · cart.php after adding Pen, Notebook, Pen, Bag and removing Bag
Your cart
Pen x 2 = Rs. 40
Notebook x 1 = Rs. 60
Total: Rs. 100
Saving Session Data in a File

Session data normally disappears when the session ends. Sometimes you want to save it and restore it in a later session – for example to remember a partly completed shopping order after the user's connection was interrupted. PHP can encode all session variables into one string with session_encode(); we write that string to a file with fopen(), fputs() and fclose():

File: htdocs/phpbook/ch31/savesession.php
<?php
session_start();
$_SESSION["username"] = "Goody";
$_SESSION["password_hint"] = "pet's name";
$_SESSION["ordernumber"] = "1234";
$sessionfile = fopen("sessionfile.txt", "w");
fputs($sessionfile, session_encode());
fclose($sessionfile);
echo "Saved: " . htmlspecialchars(file_get_contents("sessionfile.txt"));
?>
OUTPUT browser · http://localhost/phpbook/ch31/savesession.php
Saved: username|s:5:"Goody";password_hint|s:10:"pet's name";ordernumber|s:4:"1234";

session_encode() takes all session variables (but not the session id) and encodes them into a string, which fputs() writes to the file. To retrieve the data later, we start a session, read the record with fgets() (the old notes mistakenly wrote fputs() here) and pass it to session_decode(), which re-creates the session variables:

File: htdocs/phpbook/ch31/restoresession.php
<?php
session_start();
echo "Before restore: " . count($_SESSION) . " session variables<br>";
$sessionfile = fopen("sessionfile.txt", "r");
session_decode(fgets($sessionfile, 4096));
fclose($sessionfile);
echo "After restore:<br>";
foreach ($_SESSION as $k => $v) {
    echo "$k = " . htmlspecialchars($v) . "<br>";
}
?>
OUTPUT browser · restoresession.php in a brand-new session
Before restore: 0 session variables
After restore:
username = Goody
password_hint = pet's name
ordernumber = 1234

Notice that session_encode() and session_decode() are written "the other way round" with respect to fputs() and fgets(): when writing we write the result of session_encode(); when reading we decode the result of fgets(). In a real application each user's data would be stored under a unique key (for example in a database table, Part IV) rather than in one shared file.

Session Configuration in php.ini
DirectiveXAMPP valueMeaning
session.save_path"\xampp\tmp"Folder for session files.
session.namePHPSESSIDName of the session cookie.
session.gc_maxlifetime1440Seconds of inactivity after which data may be deleted.
session.cookie_lifetime0Lifetime of the session cookie (0 = until the browser closes).
session.cookie_httponly(off)Hide the session cookie from JavaScript – recommended 1.
session.use_strict_mode0Reject uninitialised session ids – recommended 1.
session.use_only_cookies1Pass the id only in cookies, never in URLs.
Advantages and Disadvantages of Session State

Advantages:

  • Session data is kept on the server; only a random id travels to the client, so it is more secure than cookies.
  • It can store large and complex data (arrays, objects) of any type.
  • Sessions work across all pages of the application automatically after session_start().
  • With a custom save handler (session_set_save_handler()), session data can be stored in a database and shared by several web servers.

Disadvantages:

  • Session variables occupy server resources (files or memory) until they are removed or expire; very many sessions can degrade performance.
  • Sessions end when the browser is closed or after a timeout, so they cannot remember a user for weeks – combine them with cookies or a database for "remember me" features.
  • Normally they depend on a cookie to carry the session id.
Session security
  • Call session_regenerate_id(true) after a successful login (prevents session fixation).
  • Use HTTPS and set session.cookie_secure, session.cookie_httponly and session.cookie_samesite.
  • Store only what you need (a user id rather than the password) and destroy the session on logout.
Key Takeaways
  • Sessions store user data on the server; the browser keeps only the session id in the PHPSESSID cookie.
  • session_start() must be called before any output on every page that uses the session.
  • Use $_SESSION['key'] to store and read; unset(), session_unset() and session_destroy() to remove.
  • session_register() and $PHPSESSID belong to removed PHP 4/5 features.
  • Typical uses: page counters, login systems, shopping carts.
  • session_encode()/session_decode() convert session data to a string and back.
  • Regenerate the id after login and protect the session cookie.
Program File

Extract the ZIP into C:\xampp\htdocs. It creates the folder phpbook/ch31 used in the file labels above; open the programs at http://localhost/phpbook/… with Apache (and MySQL, where needed) started in the XAMPP Control Panel.

Question / Answer (15 questions)

Answer : A mechanism for storing user-specific data on the server across multiple page requests, identified by a unique session id stored in a cookie on the client.

Answer : Cookies store data on the client, are limited to about 4 KB and can be read and changed by the user; sessions store data on the server, can hold much more, and send only a random id to the client, so they are more secure.

Answer : It creates a new session with a random id (sending the PHPSESSID cookie) or resumes the existing session identified by the cookie, and loads its data into $_SESSION.

Answer : Because it may send a cookie in the HTTP headers, and headers cannot be sent after output has started.

Answer : The default name of the cookie that stores the session id on the client; it can be changed with session.name or session_name().

Answer : In files named sess_<id> in the folder given by session.save_path, by default C:\xampp\tmp.

Answer : Store: $_SESSION['views'] = 1; read: echo $_SESSION['views']; on any page after session_start().

Answer : The $_SESSION array replaced it. session_register() depended on register_globals and was removed in PHP 5.4.

Answer : session_start(); if (isset($_SESSION['views'])) $_SESSION['views']++; else $_SESSION['views'] = 1; echo "Views=" . $_SESSION['views'];

Answer : unset() removes one session variable; session_unset() removes all session variables but keeps the session; session_destroy() deletes the whole session data on the server.

Answer : At the top of the page: session_start(); if (!isset($_SESSION['user'])) { header("Location: login.php"); exit; }

Answer : session_encode() returns all current session variables as one encoded string; session_decode() takes such a string and recreates the session variables in the current session.

Answer : When session_destroy() is called (e.g. at logout), when the browser is closed (the session cookie is deleted), or when the data is removed by garbage collection after session.gc_maxlifetime seconds of inactivity.

Answer : Advantages: data is kept securely on the server and can be large and complex. Disadvantages: it uses server resources until it expires, and it lasts only for the browser session.

Answer : To give the user a new session id, so that an attacker who knew or planted the old id (session fixation) cannot use it to take over the logged-in session.
MCQ Test : Check Your Understanding (5 questions)

Select an option and press Check Answer, or answer all questions and press Submit Test to see your score. Each answer comes with an explanation.

Q1. Where is session data stored?

Show Answer

Correct Answer : B. On the server
Only the session id is sent to the browser.

Q2. The default name of the session cookie is:

Show Answer

Correct Answer : B. PHPSESSID
PHPSESSID, configurable with session.name.

Q3. Which superglobal stores session variables?

Show Answer

Correct Answer : B. $_SESSION
$_SESSION holds the session data.

Q4. Which function deletes all session data on the server?

Show Answer

Correct Answer : C. session_destroy()
session_destroy() destroys the session.

Q5. Which function was removed in PHP 5.4?

Show Answer

Correct Answer : C. session_register()
Use $_SESSION instead.

Bibliography/References

The notes on this page are the author’s own compilation from the e-book PHP: Basics to Advance. Every program was run on Apache with PHP 8 and MariaDB, and the output shown is the real result of that run. The works listed below were consulted and are cited for attribution and further reading. Product names and trademarks belong to their respective owners.

  1. The PHP Group. (n.d.). PHP Manual – Sessions. https://www.php.net/manual/en/book.session.php
  2. The PHP Group. (n.d.). PHP Manual – session_start. https://www.php.net/manual/en/function.session-start.php
  3. The PHP Group. (n.d.). PHP Manual – Session Runtime Configuration. https://www.php.net/manual/en/session.configuration.php
  4. The PHP Group. (n.d.). PHP Manual – Securing Session INI Settings. https://www.php.net/manual/en/session.security.ini.php
  5. OWASP Foundation. (n.d.). Session Management Cheat Sheet. https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html