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

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

  • Explain why HTTP is stateless and why web applications need state management.
  • Distinguish client-side from server-side state management options.
  • Create, read, update and delete cookies with setcookie() and $_COOKIE.
  • Pass values between pages with query strings and read them safely.
  • List the advantages and limitations of cookies and query strings.
Why State Management?

Web pages and PHP use the HTTP protocol to communicate between a web browser and a web server. HTTP is a stateless protocol: every request is independent, and the server cannot automatically tell whether successive requests come from the same client or from different clients.

For example, if you develop a web application that shows a personalised page after a user logs on, you must keep track of the user's activities while he or she moves from page to page. HTTP does not do this for you. In addition, a page is fetched again every time it is posted to the server, so the information on the page – for example a checkbox the user ticked – is lost in each round trip unless you preserve it.

To overcome this limitation, PHP provides different state management options, divided into two categories:

CategoryOptions
Client-sideCookies, query strings (and hidden form fields)
Server-sideSession state (Chapter 31), database support (Part IV)
Client-side state management

Client-side options store information in the web page or on the client computer. They give better performance because the load on the server is lower. Their disadvantage is that only a limited amount of data can be stored, and the user can see and change it.

Server-side state management

Server-side options store information on the web server. They can manage application- and session-related information securely, but they use server resources.

Cookies

A cookie is a small piece of information stored on the client machine. A web server sends a cookie to the browser together with the page output; on every later request to the same site the browser sends the cookie back. Because HTTP is stateless, cookies are used to recognise each individual user who accesses a web page.

Cookies can be temporary or persistent:

  • Temporary (session) cookies live in the browser's memory. When the browser is closed, all session cookies are lost.
  • Persistent cookies have an expiry date and are saved as files by the browser on the client computer until they expire.

Cookies can store information about a client, a session or an application. When the browser requests a page, it sends the cookie along with the request; the server reads the cookie and extracts its value.

Setting cookies – setcookie()
Syntax
setcookie(name, value, expire, path, domain, secure, httponly)
setcookie(name, value, options_array)          // PHP 7.3+, e.g. with "samesite"
ParameterMeaning
nameThe name of the cookie.
valueThe value of the cookie (stored on the client – never store secrets).
expireThe time the cookie expires, as a Unix timestamp, e.g. time() + 3600. 0 or omitted = session cookie.
pathThe path on the server where the cookie is available (/ = the whole site).
domainThe (sub)domain that can read the cookie.
securetrue = send the cookie only over HTTPS. Default false.
httponlytrue = JavaScript cannot read the cookie (protects against XSS). Default false.

All arguments except name are optional. setcookie() must be called before any HTML output is sent, because cookies are part of the HTTP headers.

File: htdocs/phpbook/ch30/setcookie.php
<?php
setcookie("cookie1", "ICT");                          // session cookie
setcookie("cookie2", "Bhopal", time() + 3600);        // expires in 1 hour
setcookie("theme", "dark", [
    "expires"  => time() + 30 * 24 * 3600,            // 30 days
    "path"     => "/",
    "httponly" => true,
    "samesite" => "Lax",
]);
?>
<html><body>
Cookies have been sent to the browser.<br>
They will be available in $_COOKIE from the <b>next</b> request.<br>
Cookies in this request: <?= count($_COOKIE) ?>
</body></html>
OUTPUT browser · http://localhost/phpbook/ch30/setcookie.php
Cookies have been sent to the browser.
They will be available in $_COOKIE from the next request.
Cookies in this request: 0
  • cookie1 has the value ICT. Because no expiry time is given, it expires when the browser is closed.
  • cookie2 has the value Bhopal and expires in one hour (3600 seconds).
  • theme is a persistent cookie for 30 days, readable on the whole site and hidden from JavaScript.
Retrieving cookies – $_COOKIE

Cookies are retrieved through the $_COOKIE array (very old code used $HTTP_COOKIE_VARS, removed in PHP 5.4). Assuming the name of the cookie is cookie1, its value is $_COOKIE['cookie1'].

File: htdocs/phpbook/ch30/getcookie.php
<?php
echo "cookie1 = " . ($_COOKIE['cookie1'] ?? "not set") . "<br>";
echo "cookie2 = " . ($_COOKIE['cookie2'] ?? "not set") . "<br>";
echo "theme = " . htmlspecialchars($_COOKIE['theme'] ?? "light") . "<br>";
echo "All cookies:<br>";
foreach ($_COOKIE as $name => $value) {
    if ($name != "PHPSESSID") echo "&nbsp; $name => " . htmlspecialchars($value) . "<br>";
}
?>
OUTPUT browser · getcookie.php (opened after setcookie.php in the same browser)
cookie1 = ICT
cookie2 = Bhopal
theme = dark
All cookies:
  cookie1 => ICT
  cookie2 => Bhopal
  theme => dark
Deleting cookies

To delete a cookie, call setcookie() with the same name (and path) and an expiry time in the past:

File: htdocs/phpbook/ch30/delcookie.php
<?php
setcookie("cookie2", "", time() - 3600);    // expiry in the past → browser deletes it
echo "cookie2 has been deleted.";
?>
OUTPUT browser · http://localhost/phpbook/ch30/delcookie.php
cookie2 has been deleted.
OUTPUT browser · getcookie.php after delcookie.php
cookie1 = ICT
cookie2 = not set
theme = dark
All cookies:
  cookie1 => ICT
  theme => dark
Example – remembering a visitor

A cookie can remember the visitor's name and count the visits:

File: htdocs/phpbook/ch30/visits.php
<?php
if (isset($_GET['name'])) {
    setcookie("visitor", $_GET['name'], time() + 86400 * 365);
    $name = $_GET['name'];
} else {
    $name = $_COOKIE['visitor'] ?? null;
}
$count = (int) ($_COOKIE['visits'] ?? 0) + 1;
setcookie("visits", $count, time() + 86400 * 365);
?>
<html><body>
<?php if ($name): ?>
  Welcome back, <?= htmlspecialchars($name) ?>! This is visit number <?= $count ?>.
<?php else: ?>
  Welcome, new visitor! (Add ?name=YourName to the URL.)
<?php endif; ?>
</body></html>
OUTPUT browser · visits.php, third visit
Welcome back, Asha! This is visit number 3.
Advantages of cookies
  • A cookie is stored on the client computer and is read by the server when a page is requested, so no server resources are needed to maintain it.
  • A cookie is a simple text-based key–value pair, so it is easy to create and manipulate.
  • A cookie can expire when the browser session ends, or exist for a long time on the client computer, subject to the expiry rules.
Limitations of cookies
  • Cookies have a limited size – most browsers allow about 4096 bytes per cookie – so you cannot store much data.
  • Users can disable cookies; a web application then cannot store cookies on that computer.
  • Users can see and tamper with cookies, because they are stored on the client computer. Never store passwords or trust a cookie value without checking it.
  • Browsers limit the number of cookies per site.
Query Strings

If you need to send information to another page (or back to the same page) through a URL, you can use a query string. The query string is the part of the URL after the question mark (?). It provides a simple way to pass information from one page to another – for example, the selected product id, or a page number in a list.

URL with a query string
page2.php?d1=23&d2=45
  • d1 is the name of an argument and 23 its value.
  • Several arguments are separated with &.
  • The argument lasts only for that request – the next page receives it, and it is gone when the user navigates elsewhere.

Query-string arguments are read with $_GET (or $_REQUEST). Special characters in values must be encoded with urlencode() or built with http_build_query().

File: htdocs/phpbook/ch30/page1.php
<?php
$product = "PHP & MySQL Book";
$url = "page2.php?id=23&qty=2&name=" . urlencode($product);
$url2 = "page2.php?" . http_build_query(["id" => 45, "qty" => 1, "name" => "XAMPP Guide"]);
?>
<html><body style="font-family:Arial;font-size:13px">
<a href="<?= htmlspecialchars($url) ?>" id="l1">Buy the PHP book</a><br>
<a href="<?= htmlspecialchars($url2) ?>" id="l2">Buy the XAMPP guide</a><br>
Link 1 points to: <?= htmlspecialchars($url) ?>
</body></html>
OUTPUT browser · http://localhost/phpbook/ch30/page1.php
Browser output
Buy the PHP book
Buy the XAMPP guide
Link 1 points to: page2.php?id=23&qty=2&name=PHP+%26+MySQL+Book
File: htdocs/phpbook/ch30/page2.php
<?php
$id   = filter_input(INPUT_GET, "id", FILTER_VALIDATE_INT);
$qty  = filter_input(INPUT_GET, "qty", FILTER_VALIDATE_INT);
$name = $_GET["name"] ?? "";
echo "Query string received: " . htmlspecialchars($_SERVER["QUERY_STRING"]) . "<br>";
echo "Product id: $id<br>";
echo "Quantity: $qty<br>";
echo "Name: " . htmlspecialchars($name);
?>
OUTPUT browser · page2.php after clicking “Buy the PHP book” on page1.php
Query string received: id=23&qty=2&name=PHP+%26+MySQL+Book
Product id: 23
Quantity: 2
Name: PHP & MySQL Book

Notice that & in the product name was encoded as %26 – otherwise it would have started a new argument.

Advantages of query strings
  • A query string is part of the HTTP request for a URL, so no server resources are needed to keep it.
  • All browsers support passing values in a query string, so an application using query strings works everywhere.
  • Pages with query strings can be bookmarked and shared.
Limitations of query strings
  • The information is directly visible to the user in the address bar (and stored in browser history and server logs). Confidential information must never be sent this way.
  • The user can change the values easily, so they must always be validated on the server.
  • There is a limit to the length of a URL. Very old browsers allowed only 255 characters; modern browsers accept far more, but URLs longer than about 2000 characters should be avoided.
Hidden Form Fields

A third client-side technique is a hidden field in a form: <input type="hidden" name="step" value="2">. The value travels with the form's GET or POST request but is not displayed. Like a query string it can be seen in the page source and changed by the user, so it must be validated too.

Key Takeaways
  • HTTP is stateless; state management keeps information across requests.
  • Client-side: cookies, query strings, hidden fields. Server-side: sessions and databases.
  • setcookie(name, value, expire, path, domain, secure, httponly) must be called before output; values appear in $_COOKIE from the next request.
  • Delete a cookie by setting an expiry time in the past.
  • Cookies: small (about 4 KB), can be disabled, visible and changeable by the user.
  • Query strings (page.php?a=1&b=2) are read with $_GET; encode values with urlencode()/http_build_query() and always validate them.
Program File

Extract the ZIP into C:\xampp\htdocs. It creates the folder phpbook/ch30 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 : Because each HTTP request is independent; the server does not remember earlier requests, so it cannot tell by itself whether requests come from the same client.

Answer : The techniques used to preserve information about a user or page across multiple HTTP requests, such as cookies, query strings, sessions and databases.

Answer : Client-side: cookies, query strings and hidden form fields. Server-side: session state and database support.

Answer : Advantage: less load on the server, so better performance. Disadvantage: only a limited amount of data can be stored, and the user can see and change it.

Answer : A small piece of text data that a server sends to the browser, which stores it and sends it back with every later request to the same site.

Answer : A temporary (session) cookie has no expiry time and is deleted when the browser is closed; a persistent cookie has an expiry time and is stored on the client until then.

Answer : setcookie(name, value, expire, path, domain, secure, httponly): name and value of the cookie, expiry timestamp, path and domain where it is valid, secure to send only over HTTPS, httponly to hide it from JavaScript.

Answer : Cookies are sent in the HTTP headers, which must be sent before the page body; after output has started PHP cannot add headers.

Answer : Through the superglobal $_COOKIE, e.g. $_COOKIE['cookie1'], starting from the next request after it was set.

Answer : By calling setcookie() with the same name (and path) and an expiry time in the past, e.g. setcookie("cookie2", "", time() - 3600).

Answer : Limited size (about 4096 bytes per cookie), users can disable them, and users can read and tamper with them because they are stored on the client.

Answer : The part of a URL after the ? character, consisting of name=value pairs separated by &, used to pass data from one page to another, e.g. page2.php?d1=23&d2=45.

Answer : With $_GET['name'] (or $_REQUEST). Values must be encoded with urlencode() or http_build_query() so that characters like &, = and spaces do not break the URL.

Answer : The data is visible in the address bar, history and logs, it can easily be changed by the user, and the length of URLs is limited.

Answer : An <input type="hidden"> element whose value is sent with the form but not displayed; it can still be seen in the page source and modified, so it must be validated.
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. HTTP is a ______ protocol.

Show Answer

Correct Answer : B. stateless
Each request is independent.

Q2. Which of these is a server-side state management option?

Show Answer

Correct Answer : C. Session
Session data is stored on the server.

Q3. How do you create a cookie that expires in one hour?

Show Answer

Correct Answer : B. setcookie("c", "v", time() + 3600)
The expiry is a Unix timestamp: now + 3600 seconds.

Q4. Most browsers limit a single cookie to about:

Show Answer

Correct Answer : B. 4096 bytes
Cookies are limited to roughly 4 KB.

Q5. In page2.php?d1=23&d2=45, the value of d2 is read with:

Show Answer

Correct Answer : C. $_GET['d2']
Query-string values are in $_GET (and $_REQUEST).

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 – setcookie. https://www.php.net/manual/en/function.setcookie.php
  2. The PHP Group. (n.d.). PHP Manual – $_COOKIE. https://www.php.net/manual/en/reserved.variables.cookies.php
  3. The PHP Group. (n.d.). PHP Manual – http_build_query. https://www.php.net/manual/en/function.http-build-query.php
  4. MDN contributors. (n.d.). Using HTTP cookies. MDN Web Docs. https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies
  5. Barth, A. (2011). RFC 6265: HTTP State Management Mechanism. IETF. https://www.rfc-editor.org/rfc/rfc6265