Chapter 8: Processing Input

Google

Tracking traffic with cookies

Suppose you have a order form on your site which collects a lot of personal information: Name, address, phone, etc. You could use that information to fill in most of the form the next time the person visits your site. You just read it from the cookie on the person's computer when they get to the order page again.

Nothing is on the user's computer at first. But you could set a cookie with a unique ID of some kind when their browser first loaded the page. Then you could create a file on your server. The name of the file could be the ID you placed in the cookie. Are you with me so far?

OK, let's set the cookie. I've used the time() function to get the system time in seconds and followed that by a random number between 1 and 1000. That will be my unique id for the cookie.

$id = time()rand(1000);
setcookie("visit1", $id, $cookie_expire);

The name of the cookie is "visit1" and the value of the cookie is $id. Don't worry about the $cookie_expire just yet, I'll cover that in more detail a few paragraphs down. For now, I just want to to focus on the general steps we need to follow.

While the script that processes the form is running, you've got all these pieces of information in variables. You could put them all together in a long string of characters with a "separator" or "delimiter" between each item. You might use %% as a delimiter, for example.

Let's look at that part first. We'll just jump into the middle of the script and write a few lines of code. Assume that the script already exists.

# Prepare data for storage in a file
$date = date("Y-m-d h:i:s");
$visits = 1;
$data = "$fname%%$lname%%";
$data .= "$address%%$city%%$state%%";
$data .= "$zip%%$country"%%$phone%%";
$data .= "$date%%$visits";

Look at the first line. It contains s a call to the date( ) function. The argument being passed to date( ) is Y-m-d h:i:s which is a date format. It tells date( ) how to format and display the date and time. Y is the year, m is the month and d is the day. h is the hour and s is the second. But what about the minute? Well, we've already used m for the month so we need something different for the minute. The folks who created PHP chose i to stand for the minute.

This particular format results in a date being stored like this:

2004-07-15 08:15:32

Since this is the first visit by this person, I've set the visit count to 1.

Next we put all the data items into a string. I put the first two items in using the = operator and tacked the rest onto the end of the string with the .= operator.

Now I'll open a new file on the server and put the data into it:

$myfile = "cgi-bin/$id";
$fp = fopen($myFile,"w");
fwrite($fp, $data)
fclose($fp);

I'm sure you noticed that the file was being created in the cgi-bin folder. I had a very good reason for doing that. You see, the cgi-bin folder is almost never accessible to web surfers for reading. Try it yourself: Just type http://www.somesite.com/cgi-bin into your browser. This folder will almost certainly not contain an index file, so you might expect to see a directory listing instead. But that's not what happens!

What does happen is you get an Error 403: You are forbidden to access files in this folder (or something similar to that). Sometimes a webmaster will redirect these server errors so they load a custom page. That page might tell you the file was not found. Try it on Google if you'd like to see what I mean.

The point is that you're not allowed to see what's in cgi-bin unless you own the site. In almost any other folder it's different. If there's no index file, you'll get a listing of the files in that folder. You could right-click on any file on the list and copy it to your hard drive. Then you could read it in NotePad or whatever editor you like.

Since the data you're putting into this little file is someone's personal information, you sure as heck don't want to risk having an unauthorized (and probably unknown) person reading it! So I'm showing you to put it in a very safe place. You'll see this technique again in the next chapter. But let's move on.

What happens when the same person visits your site again? They have a cookie with their ID in it. So you read that cookie when they request your page and write a new cookie with the information from the little file you created last time. That looks like this:

# read the original cookie and get the ID
$visit1 = $_COOKIE["id"];
# open the file whose name is the cookie ID
$myFile = $id;$fp = fopen($myFile,"r");
# read the contents of the file into $data
$data = fread($fp, filesize($myFile));
#set a new cookie
setcookie("user", $data, $cookie_expire,"mysite.com");

Now there's a cookie set on the visitors computer! Do you know what's in it? Sure you do! Its name is "user", its value is:

$fname%%$lname%%$address%%$city%%$state%%$zip%%$country"%%$phone%%$date%%$visits";

Actually, the value of the cookie contains the real data you put there - not the variable names. So it looks more like this:

John%%Smith%%12 Farley St.%%Nome%%AL%%99764
USA%%(845) 459-6377%%2004-07-15 08:15:32%%1

The domain is "mysite.com" which allows you to read it later. When you do, you'll get whatever is in the value field of the cookie. Since it has those nifty separators (%%), you can use explode() to put them into an array. Then you take each element in the array and copy (assign) it to a variable.

Here, the first element would be "John". You know the first name is the first thing you put into the cookie data so you can set $fname equal to $cookie_data[0] if $cookie_data is the name you gave to the array. Continue with the other items, putting them into the local variables $lname, $address, etc.

Whew! You've set the cookie with just an ID, stored the user's data in a file, read it on a later visit so you'd get the name of the file, opened the file, prepared the data to be baked into a cookie and put the cookie in your visitor's back pocket. From now on, you can read the cookie and get the info to pre-fill an order form with this user's data!

Plus, you can add 1 to $visits each time. That way you'll know how many times this person has visited your site. You can update the date to show when the last time they were here and display a message like "Welcome back, John Smith. The last time I saw you in here was on 2004-07-15 at 08:15:32."

What about that little file? You still have it. If you'd added the ID to the data you wrote back to the cookie, you could use it to find the file again. Then you could write the most recent data back to the file. Over time, you'd collect a bunch of these little files. There would be one for each visitor. Of course all those little files would clutter up your server...

This method could be extended by making one big file instead of a lot of little ones. You could insert one line into the file for each cookie and use the ID as an index into the file. By reading the file into an array of lines and scanning each line for the ID, you could locate the right line for this visitor. But what if you had thousands of lines in the file?

Hmmm...it would take longer and longer to locate a line near the end of that file...wouldn't it? And it would also take longer and longer to open and read the file. Would you like to see a better way? One that wouldn't slow down your web server enough for anyone to notice? OK, you talked me into it.

Take what you just learned and give it a twist. Instead of storing the user's information in a file and in a cookie just store the ID in the cookie. Use the ID as a key to an entry in a database table. Now we're cookin'!

Each time you get some information from the user, use the key in the cookie to find the user's record in the database. Write the info into the database. Now it's even safer because nobody without your database password, etc. can ever see it. Plus, a database has a much faster indexing system than a text file could ever have.

The next section will show you another cool method for tracking traffic. It uses cookies and a database together in a totally different way.

Previous Page   Table of Contents   Next Page

Copyright © 2004 Steve Humphrey