State Maintenance

The most direct way in which you'll be involved with state
in PHP programs is when trying to preserve variable values between page requests
because each page is its own program, and once the program is done processing,
all variables and values are lostâ€”the program's done, and everything is erased
out of memory. Unlike desktop applications, which maintain data in memory until
you shut them down, a PHP program runs only when a page request activates it,
and then only until processing is completed and/or HTML or text content is
returned to the user.

PHP is able to bridge the gap between each request-response and
the next, providing persistence of dataâ€”and, yes, prolonged interactivity. This
process of continually updating the server with information, a major ingredient
in most interactive sites, is necessary to maintain a session. Session
maintenance is how you refer to a series of interactions,
beginning with the user accessing or logging on to a site, and ending with the
user logging out or being timed out for inactivity.

The key to this process is usually a cookie
(a small piece of data stored on the client's computer) or some sort of a
variable that the client and server pass back and forth, often called a session key. These cookies and keys are used to help the
server know which client it is interacting with for any given request. Just as a
username identifies a user to a system, a session key (or an appropriate cookie)
identifies a client to a Web site.

Sessions also maintain state across page requests and you'll
examine them in detail a little later. First, take a look at some other methods
available to you, including the use of hidden form fields, query strings,
databases, and cookies.

Hidden Form Fields

You've seen how hidden form fields work to send data (coded
by the designer) back to the server when the form is submitted. If you want to
maintain state using hidden form fields (for example, a unique value
representing a product the user is working with, such as the product ID), you
can simply place the current product ID value into a hidden form field. Of
course, the idea is that you would have the user select the product from a
drop-down box (the select element) and then submit the form, using something
like this code:

So the next time he submits this form, part of the data
submitted would be chosen_product_id, which PHP would
turn into $chosen_product_id, and which you could then
use anytime you wanted to perform processing on the product he chose, no matter
how many page requests ago he chose that product. Don't forget, though, you'll
need to populate that same hidden form field value each time the user requests
another page or you'll lose that value.

Query Strings

Query strings can be used in exactly the same way as hidden
form fields to maintain state values across page requests. However, as
previously discussed, their name/value pairs are displayed for all to see in the address bar of the browser, along with the URL. This is a very
insecure method of transmitting data, and as you've probably guessed, easy for
malicious users to break, disable, or otherwise mess with.

Databases

The mechanics of databases and database access haven't been
discussed yet (you'll get to it but you're certainly aware that databases are useful for
storing structured information persistently (meaning that the data is retained
even if the server is turned off), so you can understand why databases are
useful for storing data across page requests. Basically, if you don't mind the
extra overhead of making a query on the database each time a page request
occurs, you can use a table in the database to store all pertinent data that
must be preserved across page requests. The downside, of course, is the overhead
involved in those database connections, and the extra effort building the
database in the first place.

Cookies

So what are cookies? They're a quick (and some would say
messy) method of storing, on the client's computer, small snippets of data that
you want to persist between separate visits to a Web site. They aren't very
powerful or reliableâ€”you certainly wouldn't want to use them for permanent data
storage, because the mere act of switching browsers completely obliterates all
your old cookies. But they can be very handy for a wide variety of things. Some
of the most common examples of cookie use include the following:

Storing a user's aesthetic preferences for a specific
site.

Storing a user key (or keys) that can be used to link users
with their personal dataâ€”as used in countless shopping basket features, for
example.

Providing a semi-permanent session key, enabling a user to
remain logged on to a site until he explicitly asks to leave it or the browser
closes.

Cookies are best used for small, helpful but non-critical things.
One of the best examples of cookie use is to store preferences describing how a
user wants your site to appear. Although the capability to customize a site's
color scheme is a nice perk for users, those who can't (or won't) use cookies
won't be missing much.

Intended as innocuous "helpers" for Web developers, cookies have
built up a bad reputation in recent years. They are often overused (for example,
to store large quantities of data which is really best kept on the server end)
and sometimes even abused (to gather information on consumers without their
knowledge, for instance). If used sparingly and responsibly, though, cookies can
be useful in a number of situations. They tend to be most useful:

In situations where you know for a fact that all the
visitors to your site will have cookie support enabledâ€”on corporate and
educational intranets, for example.

To add bells and whistles to a siteâ€”features that add to a
site's appeal but aren't required to make use of it.

Messing Around with Cookies

Exact details of how cookies are implemented vary from
browser to browser, but certain important points apply across the board, and
these are as follows:

A cookie is a short piece of data that can be used to store
a variable's name and value, along with information on the site from which it
came and an expiry time.

Cookies provide client-side storage, usually held in files
on the client machine's hard drive.

Web sites can usually only modify their own cookies.

They can be accessed and (if the appropriate security
criteria are met) altered at will by the Web server from which they were
originally sent.

When a client accesses a Web site that uses cookies, the Web
server tells the client (usually a Web browser) to store away a given piece of
data for later use. The client is then responsible for storing that data away.
Cookie-supporting browsers accomplish this by storing the data in a file named
after the site the cookie belongs to, in a directory they keep reserved for this
purpose. On subsequent requests to that site, the client sends back a copy of
that dataâ€”the data persists on the client side until a specified period expires,
causing it to be removed from the system. This specified period is set by the
server when it tells the client to create the cookie, and is basically a number
of seconds for which the client should keep the cookie. If the server tells the
client to set an expiry period of zero seconds, the browser should keep the
cookie only until the user quits the browser application.

Because cookies are kept on the client side, they're not under the
control of the server once they've been created. Users can elect to delete
cookies themselves, often simply by clicking a button in their browser, or by
deleting the browser's cookie files. They could also edit the contents of the
files if the urge took them. Just because you wrote what's in the cookie,
doesn't mean you should always expect the right data to come back!

Essentially, cookies are the server telling the client "here's
something to remember; remind me of it when you come back next time." Next time
could be anything from when you click that link two seconds from now to when you
come back next week. That's some serious persistence! It's a little like being
at a conference where delegates can be identified by their name badges for as
long as they care to wear them.

Web servers send clients cookies in HTTP headers, which are sent
before any HTML text. Likewise, clients send back those cookies using HTTP
headers. A client knows which cookies to share with a Web site, based on the
server and path the client is currently accessing. So, if you're accessing www.php.net, the browser doesn't send any cookies it
received from www.wrox.com.

When a cookie is set, a server name and path name can
optionally be setâ€”this limits access to the cookie to the specified server
and/or path on that server. Clients use this information to determine whether
they should send any given cookie. A cookie-enabled browser generally sends any
and all cookies that it thinks applicable to a given site in the headers of any
given access.

Set and Retrieve Cookies

PHP, as a modern Web scripting language, comes with full
support, and setting cookie variables is as simple as making a call to setcookie(). As with header(), setcookie() must be called before any HTML is printed to the
client's browser because cookies are set in the HTTP headers, which must be sent
before any HTML.

The setcookie() function takes six
parameters, of which the first three are by far the most important: These are,
in order:

A string to be used as the name of the variable.

A string to be used as the value of the variable.

A UNIX timestamp denoting the time at which the cookie will
expire.

A UNIX timestamp is simply a long integer that represents a time
and date by counting seconds since midnight on 01/01/1970. You can get the
current time in this form by using the function time().
If you want to set a cookie to expire an hour from now, simply specify time() + 3600 for the third parameter.

The last three parameters to setcookie()
are less frequently used:

The path to whose files the cookie is relevant; the browser
doesn't return cookies that are from inappropriate paths. For example, if you
set this parameter to /my/path/number/one and accessed a page in
/my/path/number/two, your browser wouldn't send the cookie. If you went back to
a page in /my/path/number/one, the browser would send the cookie.

The domain to which the cookie applies; same rules apply as
to the preceding parameter. This parameter may be useful if your Web server
hosts multiple domains.

An integer called secure. Set it to
1 if you only want your cookie to be sent when requesting an SSL-encrypted page.
(The cookie won't be stored in an encrypted form on the client's hard drive;
this setting merely ensures that the cookie will be encrypted for transmission
across the Internet.)

In the simplest possible situation, you could leave off these last
three, so that a typical call to setcookie() might look
like this:

setcookie("fontprefs", "", time()+3600);

Accessing cookies is even simplerâ€”there's nothing to call at all!
Just as it does with POST variables, PHP automatically
puts cookie information in the global domain, so it's as simple to use cookie
values as it is to use any other variables. For example, the value of a received
cookie called fontprefs is automatically be available
throughout the script as the global variable $_COOKIES['fontprefs'].

There are several ways to delete a cookie. Of course, if the
client knows where to look on his machine, he can always edit or delete the
files in which cookies are stored. However, it's sometimes useful to be able to
get the server to delete (or "eat") a cookie, and if this is the case, there are
two main options:

Reset the cookie's expiry time to a time in the past: setcookie("num", "0",time()
-9999);, for example.

Reset the cookie, specifying only its name: setcookie("fontprefs");, for example.

Try
It: Out Use Cookies To Store User Preferences

Start Example:

Here's a script that stores user-selected choices for font
size and typeface in a cookie. On subsequent visits to the page, the cookie is
examined, and the preferences stored in it remain in effect. Save the code as
cookies.php:

An expiry time of one hour from the current system time is
specified for each cookie.

A pair of arrays containing available font sizes and typefaces are
defined, and list boxes subsequently put into the form use these arrays to
specify all the possible options. When the form is submitted, the values chosen
are posted back to your script to use:

Nothing too tricky there. When you run cookies.php for the first time, both your form variables and
your cookie variables are empty. If you make a selection from each of the list
boxes and click the Submit Query button, you'll fill the form variables with
values, and these are echoed to the screen.

So what does this tell you? The form variables type_sel and size_sel have now been
updated with the inputs selected in the preceding form. Note that the cookies
are both still emptyâ€”don't worry, they're present all right; all you need to do
now is refresh the page.