Cookies: Preserving State and a Tasty Treat
As you are probably aware, HTTP is a stateless protocol. This means that there is no information, or state, retained in the browser between different HTTP transactions. Cookies are the mechanism that allow a Web application to store state information in the browser. A cookie is a small variable stored in the browser that can be set by the server application. Cookies allow you to store user preferences, login information, session variables, and more. The best way to think of a cookie is a name-value pair.
Interestingly, cookies are not part of the official HTTP specification; they were developed by Netscape and then rapidly adopted by the entire Internet industry. Cookies have become such a standard that it is very common to not be able to access certain websites without cookies.
Cookies can be limited to a particular URL or domain, as well as limited either to the current session or set to a particular expiration date.
Here's what a low-level HTTP transaction with cookies looks like:
That's how the cookie was set. Technically it now exists within the context of the user's browser as a small text file that contains the values for the site. Now if the user returns to the Feedster.com website, the browser will automatically realize, "Hey I have a cookie for this site; I should send it," thus sending this information:
The next time the browser visits the site, the client should recognize that a cookie is needed and will send the following:
GET /index.php HTTP/1.0 [Normal headers here] Cookie: user_id=265
PHP has excellent built-in support for programming with cookies. Most of this is centered on the built-in $_COOKIE variable and the setcookie function. Suppose that you're writing a PHP program and you want to access a named user_id that contains the ID number of the user. All you need is the code that follows:
<?php $user_id = $_COOKIE['user_id']; ?>
As you can see, PHP automatically handles all the underlying HTTP magic to make cookies easy. Setting cookies is only a little bit more complex.
<?php setcookie('user_id', 12); ?>
An important thing to understand about cookies is that they are implemented as an HTTP header. HTTP headers must precede the start of the document being sent via HTTP. This means that you can't start outputting a document in PHP (for example, via a print statement) and then set the cookie afterward. That will cause an error and fail to set the cookie. When you are structuring your PHP code, you need to keep this in mind. If you can't set your cookie before outputting a portion of your document, look into the PHP ob_start buffering feature, which will let your cookies be set after content is output. The magic here is that because the output is buffered, the cookie still actually precedes the output.
A closing note about cookies is that they tend to be tricky to program with. You will quite often find messages on the different mailing lists complaining about cookies. A useful debugging technique is to have multiple Web browsers installed on your machine so you can test different cookies at the same time. For example, you might use Mozilla for testing with Shelley's user account and cookies and use Firebird for testing with Scott's user account and cookies.