Build Your Own Database-Driven Website Using PHP MySQL [Electronic resources]

Kevin Yank

نسخه متنی -صفحه : 190/ 92
نمايش فراداده

Chapter 12: Cookies and Sessions in PHP

Cookies and sessions are two of those mysterious technologies that are almost always made out to be more intimidating and complex than they really are. In this chapter, I’ll debunk those myths by explaining in simple language what they are, how they work, and what they can do for you. I’ll also provide practical examples to demonstrate each, with hints as to how these can be expanded to add exciting new features to your own Website!

Cookies

Most computer programs these days preserve some form of state when you close them. Whether it be the position of the application window, or the names of the last five files you worked with, the settings are usually stored in a small file somewhere on your system, so they can be read back the next time the program is run. When Web developers took Web design to the next level, and moved from static pages to complete, interactive, online applications, there was a need for similar functionality in Web browsers—so cookies were born.

A cookie is a name/value pair associated with a given Website, and stored on the computer that runs the client (browser). Once it’s set by a Website, all future page requests to that same site will also include the cookie, until it expires. Other Websites cannot access the cookies set by your site, and vice versa, so, contrary to popular belief, they’re a relatively safe place to store personal information. Cookies in and of themselves cannot violate a user’s privacy.

Illustrated in "Cookie Life Cycle" is the life cycle of a PHP-generated cookie.

???

First, a Web browser requests a URL that corresponds to a PHP script. Within that script is a call to the setcookie function built into PHP.

???

The page produced by the PHP script is sent back to the browser, along with an HTTP set-cookie header that contains the name (e.g. mycookie) and value pair of the cookie to be set.

???

When it receives this HTTP header, the browser creates and stores the specified value as a cookie named mycookie.

???

Subsequent page requests to that Website contain an HTTP cookie header that sends the name/value pair (mycookie=value) to the script requested.

???

Upon receipt of a page request with a cookie header, PHP automatically creates an entry in the $_COOKIE array[1] with the name of the cookie ($_COOKIE['mycookie']) and its value.

Cookie Life Cycle

In other words, the PHP setcookie function lets you set a variable that will be automatically set by subsequent page requests from the same browser! Before we examine an actual example, let’s take a close look at the setcookie function.

setcookie(name[, value[, expirytime[, path[, domain[, secure]]]]]);

Like the header function we saw in "Storing Binary Data in MySQL", the setcookie function adds HTTP headers to the page, and thus must be called before any of the actual page content is sent. Any attempt to call setcookie after some HTML, for example, has already been sent to the browser, will produce a PHP error message.

The only required parameter for this function is name, which specifies the name of the cookie. Calling setcookie with only the name parameter will actually delete the cookie that’s stored on the browser, if it exists. The value parameter allows you to create a new cookie, or modify the value stored in an existing one.

By default, cookies will remain stored on the browser, and thus will continue to be sent with page requests, until the browser is closed by the user. If you want the cookie to persist beyond the current browser session, you must set the expirytime parameter to show the number of seconds from January 1st, 1970 to the time at which you want the cookie to be deleted automatically. The current time in this format can be obtained using the PHP time function. Thus, a cookie could be set to expire in one hour, for example, by setting expirytime to time() + 3600. To delete a cookie that has a preset expiry time, change this expiry time to represent a point in the past (e.g. one year ago: time() – 3600 * 24 * 365). Here’s an example:

// Set a cookie to expire in 1 year
setcookie('mycookie','somevalue',time()+3600*24*365);
// Delete it
setcookie('mycookie','',time()–3600*24*365);

The path parameter lets you restrict access to the cookie to a given path on your server. For instance, if you set a path of '/~kyank/' for a cookie, then only requests for pages in the ~kyank directory (and its sub-directories) will include the cookie as part of the request. Note the trailing “/”, which prevents other scripts in other directories beginning with /~kyank from accessing the cookie. This is helpful if you’re sharing a server with other users, and each user has a home directory. It allows you to set cookies without exposing your visitors’ data to the scripts of other users on your server.

The domain parameter serves a similar purpose; it restricts the cookie’s access to a given domain. By default, a cookie will be returned only to the host that originally sent it. Large companies, however, commonly have several host names for their Web presence (e.g. www.company.com and support.company.com). To create a cookie that is accessible by pages on both servers, you would set the domain parameter to 'company.com'. Note the leading “.”, which prevents another site at somecompany.com from accessing your cookies on the basis that their domain ends withcompany.com.

The secure parameter, when set to 1, indicates that the cookie should be sent only with page requests that happen over a secure (SSL) connection (i.e. with a URL that starts with https://).

While all parameters except name are optional, you must specify values for earlier parameters if you want to specify values for later ones. For instance, you can’t call setcokie with a domain value if you don’t also specify some value for the expirytime parameter. To omit parameters that require a value, you can set string parameters (value, path, domain) to '' (the empty string) and numerical parameters (expirytime and secure) to 0.

Let’s now look at an example of cookies in use. Say you wanted to display a special welcome message to people on their first visit to your site. You could use a cookie to indicate that someone had been to your site before and then only display the message when the cookie was not set. Here’s the code:

if (!isset($_COOKIE['visited'])) { // First visit
echo("Welcome to my Website! Click here for a tour!");
}
setcookie('visited','1',time()+3600*24*365); // 1 year 

At first glance, this code would seem to do exactly what we want it to. Unfortunately, it runs into a common pitfall—the welcome message is printed out before setcookie is called. Instead of setting the cookie, PHP displays an error message to inform you that HTTP headers cannot be added after page content has already been sent.

To fix the problem, we call setcookie before we print out the message:

setcookie('visited','1',time()+3600*24*365); // 1 year
if (!isset($_COOKIE['visited'])) { // First visit
echo('Welcome to my Website! Click here for a tour!');
}

This may seem wrong at first glance. If you’ve never worked with cookies before, you might think that the welcome message will never be printed out, because the cookie is always set before the if statement. However, if you think back to the cookie life cycle, you’ll realize that the cookie isn’t actually set until the browser receives the Web page that’s generated by this script. So the cookie that is created by the setcookie line above won’t actually exist until the next time a page is requested.

Instead of simply tracking whether or not the user has visited before, you could instead track the number of times he or she has visited. Here’s the complete example containing all the HTML tags, which is also included in the code archive (cookiecounter.php). Notice how I’ve structured the document to ensure that setcookie happens before any page content is output.

<?php
if (!isset($_COOKIE['visits'])) $_COOKIE['visits'] = 0;
$visits = $_COOKIE['visits'] + 1;
setcookie('visits',$visits,time()+3600*24*365);
?>
<l>
<head>
<title> Title </title>
</head>
<body>
<?php
if ($visits > 1) {
echo("This is visit number $visits.");
} else { // First visit
echo('Welcome to my Website! Click here for a tour!');
}
?>
</body>
<l>

Before you go overboard using cookies, be aware that browsers place a limit on the number and size of cookies allowed per Website. Most browsers will start deleting old cookies to make room for new ones after you have set 20 cookies from your site. Browsers also enforce a maximum combined size for all cookies from all Websites, so an especially cookie-heavy site might cause your own site’s cookies to be deleted. For these reasons, you should never store information in a cookie if your application relies on that information being available later on. Instead, cookies are best used for convenient features like automatically logging in a user. If the cookie that contains a visitor’s automatic login details is deleted before that person's next visit, he or she can simply re-enter the user name and password by hand.

[1]In versions of PHP prior to 4.1, this array was named $HTTP_COOKIE_VARS instead of $_COOKIE. This old name also remains in current versions of PHP for backwards compatibility.