Articles: 843 | Categories: 148   
   
   
Home Articles Contact Us
 
 
 
 
Using Cookies (0 Comments)
Admin: Posted Date: March 3, 2010

This chapter describes: What is a Cookie? Sending and Receiving Cookies, Output Control Functions, Persistent Cookies, and Other Cookie Properties.

Using Cookies 

This chapter describes:

  • What is a Cookie?
  • Sending and Receiving Cookies
  • Output Control Functions
  • Persistent Cookies
  • Other Cookie Properties

What is a Cookie?

Cookie: A small amount of information sent by a Web server to a Web browser, saved by the browser, and sent back to the server later. Cookies are transmitted inside the HTTP header.

Cookies move from server to browser, and back to server as follows:

Web         Web         Local       Web           Web
Server      Browser     System      Browser       Server
Send        Receive     Save        Send back     Receive
cookies --> cookies --> cookies --> cookies   --> cookies

As you can see from the diagram, cookies are actually saved to the hard disk of Web browser user's machines. Many users are concerned about this. But I think it is pretty safe to allow your browser to save cookies.

If you are really concerned, you can change your browser's settings to reject cookies. But this may cause many Web based applications fail to run on your browser.

Sending and Receiving Cookies

Cookies are supported in PHP in the following ways:

1. setcookie() - A built-in function that defines a cookie to be sent along with the rest of the HTTP headers. Like other headers, cookies must be sent before any output from your script (this is a protocol restriction). This requires that you place calls to this function prior to any output, including and tags as well as any whitespace. If output exists prior to calling this function, setcookie() will fail and return FALSE. setcookie() can be called using the following simple syntax:

bool setcookie(string name, string value)

where "name" is the name of the cookie, and "value" is the value of the cookie.

2. $_COOKIE[] - A pre-defined associate array that stores cookies submitted by the browser.

To demontrate how to send and receive cookies, I wrote the following PHP script page, CookieTest.php:

\n");
print("Cookies added by the server:\n");
print("   $cookieName: $cookieValue\n");
print("\nCookies received by the server:\n");
foreach ($_COOKIE as $k => $v) {
print "   $k = $v\n";
}
print "
\n"; ?>

I opened this page with IE, I got:

Cookies added by the server:
Cookie_1: My cookie value
Cookies received by the server:

I clicked the refresh button on the IE window, I got:

Cookies added by the server: Cookie_2: My cookie value Cookies received by the server: Cookie_1 = My cookie value

What happened here was that when I opened the page the first time, the server received no cookie from the browser's request. But my page added one cookie named as "Cookie_1" to the response.

When I clicked the refresh button, the browser sent my cookie back to the server in the request. Then my page added another cookie named as "Cookie_2" in the response.

If I keep clicking the refresh button, more and more cookies would be added to the request and response. But there is a limit. The browser will only take up to 20 cookies from one Web server.

Output Control Functions

As you can see from setcookie() definition, the PHP engine provides no buffer for the HTTP response body. That means as soon the PHP script starts to send output to the HTTP response body, the HTTP header block will be finalized, and no allowed to change.

But this default behavior can be altered by calling output control functions:

  • setcookie() must be called before any output to the HTTP response. The main reason is that PHP is not buffering the HTTP response. But you can alter this behavior by using ob_*() functions.
  • ob_start() - A built-in function that turns on output buffering.
  • flush() - A built-in function that flushes out the contents of the output buffer to the HTTP response body.


Of course, default behavior can also be altered by the configuration file, php.ini. Open php.ini and set the following line:

output_buffering = 4096

The above configuration line tells the PHP engine to turn on output buffering, and set the buffer size to 4096 bytes. Once "output_buffering" is turned on, you don't have to call ob_start() in your scripts.

To test the PHP engine default behavior, I modified CookieTest.php into CookieOutputBuffer.php:

\n"); print("Adding cookies by the server:\n"); $numCookies = count( array_keys($_COOKIE) ); $numCookies++; $cookieName = "Cookie_$numCookies"; $cookieValue = "My cookie value"; print(" $cookieName: $cookieValue\n"); setcookie($cookieName, $cookieValue); print("\nCookies received by the server:\n"); foreach ($_COOKIE as $k => $v) { print " $k = $v\n"; } print "\n"; ?>

I then opened php.ini and set the following line:

output_buffering = 0

Running IE on CookieOutputBuffer.php gave me this:

Adding cookies by the server: Cookie_2: My cookie value Cookies received by the server: User = Herong Yang PHP Warning: Cannot modify header information - headers already sent by (output started at ...\CookieOutputBuffer.php:4) ...

Now I truly beblieve that PHP engine's default behavior is no output buffering. Make sure to change "output_buffering" back to 4096 before continuing to the next test.

 

Persistent Cookies

There are two kinds of cookies: persistent cookies and temporary cookies.

A persistent cookie is stored in a file on your computer. It remains there when you close Internet Explorer. The cookie can be read by the Web site that created it when you visit that site again.

A temporary or session cookie is stored only for your current browsing session. It is deleted from your computer when you close Internet Explorer.

The default behavior of setcookie(name,value) is to set a cookie as a temporary cookie. To set a persistent cookie, we need to add another parameter to the setcookie() function call as in the following syntax:

bool setcookie(string name, string value, int expire)

where "expire" specifies when this cookie should be expired. If the expiration time is a future time, like 30 days from today, this cookie will be set as a persistent cookie. Note that "expire" should be represented in number of seconds since the epoch. The best way to set "expire" is use the time() function, which represents the current time in number of seconds since the epoch. Example, 30 days from today can be expressed as "time()+60*60*24*30".

If "expire" is not given, a temporary cookie will be created.

To show you how to set a persistent cookie, and how the cookie is store in a file, I wrote the following PHP script page, CookiePersisted.php:

\n"); print("Cookies added by the server:\n"); print(" $cookieName: $cookieValue\n"); print(" Expires at: $expiration\n"); print "\n"; ?>

I opened this page with IE, I got:

Cookies added by the server: User: Herong Yang Expires at: 1134531525

To find out in which file this cookie is stored in my computer, I clicked at IE "Tools" menu, selected "Internet Options...". and clicked the "Settings..." button in the "Temporary Internet files" section of the "General" tab. I saw where is my "Temporary Internet files folder". So I went to that folder, and saw a cookie file named something like "Cookie:user@localhost/". I double clicked on that file, and managed to open it in notepad:

User Herong+Yang localhost/ 1024 3801469056 29753439 3934260416 29747404 *

Actually, I saw a lots of other cookie files created by other Web sites that I have visited in the past. I deleted all of them.

Other Cookie Properties

A cookie also has two other properties:

1. "domain" - A property that defines the domain of Web servers to which this cookie should be made available. Web browsers will send a cookie back to a Web server when the Web server matches its defined domain. Web browsers will never send back a cookie to a domain other than its defined domain.

For example, if a cookie's domain is www.google.com, the browser will send back this cookie to the server only when the browser is visiting www.google.com. The browser will never send back this cookie to www.yahoo.com.

To make a cookie available for all sub domains of a top level domain, set the domain property to the top level domain name. For example, if a cookie's domain is set to ".google.com", this cookie will be available to all google sub domains, like groups.google.com and gmail.google.com.

2."path" - A property that defines a Web server path to which this cookie should be made available. Web browsers will send a cookie back to a Web server when the Web server matches its defined domain, and the requested page matches its defined path. Web browsers will never send back a cookie to requested path other than its defined path.

Note that the defined path also includes all its sub paths. For example, if a cookie's domain is "www.amazon.com", and path is "/order/", then a browser will send back this cookie for requests like "http://www.amazon.com/order/checkout.html", and "http://www.amazon.com/order/report/invoice.html". But a browser should not send back this cookie for requests like "http://www.amazon.com/catelog/book.html".

The setcookie() function offers two more parameters to allow you to set "domain" and "path" properties on a cookie as in the following syntax:

bool setcookie(string name, string value, int expire, string path,
string domain)

where "path" specifies the cookie's path property, and "domain" specifies the cookie's domain property. If "path" is not given, the cookie will have "/" as the default path. If "domain" is not given, the cookie will have the current domain as the default domain.

Okay. Let's play the properties with the following script, CookieProperties.php:

\n");
print("\nAdding a cookie with default properties:\n");
$cookieName = "User";
$cookieValue = "Herong Yang";
$expiration = time()+60*60*24*30;
setcookie($cookieName, $cookieValue, $expiration);
print("   Name: $cookieName\n");
print("   Value: $cookieValue\n");
print("   Expiration: $expiration\n");
print("\nAdding a cookie with non-default properties:\n");
$cookieName = "Book";
$cookieValue = "Herong's Tutorial Notes on PHP";
$expiration = time()+60*60*24*30;
$path = "/";
$domain = "localhost";
setcookie($cookieName, $cookieValue, $expiration, $path, $domain);
print("   Name: $cookieName\n");
print("   Value: $cookieValue\n");
print("   Expiration: $expiration\n");
print("   Path: $path\n");
print("   Domain: $domain\n");
print("\nCookies received by the server:\n");
foreach ($_COOKIE as $k => $v) {
print "   $k = $v\n";
}
print "
\n"; ?>

Ran this script in IE, I got:

Adding a cookie with default properties:
Name: User
Value: Herong Yang
Expiration: 1134622043
Adding a cookie with non-default properties:
Name: Book
Value: Herong's Tutorial Notes on PHP
Expiration: 1134622043
Path: /
Domain: localhost

Clicked the refresh button on IE, I got:

Adding a cookie with default properties:
Name: User
Value: Herong Yang
Expiration: 1134622059
Adding a cookie with non-default properties:
Name: Book
Value: Herong's Tutorial Notes on PHP
Expiration: 1134622059
Path: /
Domain: localhost
Cookies received by the server:
User = Herong Yang

Apparently, my script did not set the properties correctly. The browser should have sent back my second cookie also. So either the "path=/" or "domain=localhost" did not match my local IIS environment. I could not figure it out why.

Conclusion

  • setcookie() must be called before any output to the HTTP response. The main reason is that PHP is not buffering the HTTP response. But you can alter this behavior by using ob_*() functions.
  • A persistent cookie is stored in a cookie file on the browser's local machine.
  • A persistent cookie can have a expiration time to be expressed in number of seconds since epoch.
  • Web browser will only send back a cookie when both domain and path match the requested domain and path.
  • To make a cookie available for all sub domains of a top level domain, set the domain property to the top level domain name.

 

 

 
 
Add a Comment:
 
(You must be signed in to comment on an article. Not a member? Click here to register)
   
Title:

Comments: