Cookie Example: Part I -- Retrieving the Cookie
June 14, 1999
Scenario: we're coding a basic front end to a search engine,
which consists of a few form fields, as seen below.
As an added twist to the site, we will use cookies to
"remember" the values of these fields for the
next visit by this user. Thus, if a particular user prefers
verbose listings with 100 results per page, our site
will recall this on each visit, until changed by that user.
This, again, is a form of maintaining state across
sessions.
The code for this scenario actually requires two CGI scripts:
the script which retrieves the cookie and creates
the above form field (drawform.cgi), and the script
which sets the cookie and performs the search (dosearch.cgi).
Of course, we're not looking at coding a search engine, but
the bit of code which sets the cookie will reside inside
the fictitious search engine script.
While we walk through the code for drawform.cgi, you
may also wish to
pop open a window containing the whole script.
Starting out, we prepare the CGI environment
for use in the Perl script:
#drawform.cgi
#!/usr/local/bin/perl
#output form fields that "remember" last state of being.
use CGI;
$cgiobject=new CGI;
$cgiobject->use_named_parameters;
After creating a new instance of the CGI object, we enable
the "use_named_parameters" feature, which
simply provides a more specific way to call future methods
of the CGI object -- something we'll see in a moment.
#retrieve cookie data
$cookie_data=$cgiobject->cookie("searchform");
if ($cookie_data)
{ &crumble_cookie;
$greeting="Welcome back!" }
else { &init;
$greeting="Hello First Timer!" }
Here we attempt to retrieve the cookie previously stored
on this visitor's machine. The cookie() method
of the CGI object accepts the name of the cookie (which
was set when creating the cookie), in this case
"searchform".
If the cookie named "searchform", created by
this web site, exists on the visitor's machine then its
data is assigned to the variable $cookie_data.
If no such cookie has been set -- meaning that the user has
not visited before or else their cookie has since expired --
no data will be returned. The conditional if
clause evaluates these two possibilities: if the cookie
did exist, its data is analyzed by the crumble_cookie
subroutine and a welcome message variable is set; if the
cookie was empty, the form variables are sent to some
default values by the init subroutine and a different
welcome message is set.
Although we won't see the crumble_cookie subroutine
for a little while, suffice it to say that it parses
the cookie data and breaks it down into the values we stored
in it; in this case, we put three variables and three
values into the cookie which represent states of form fields.
print $cgiobject->header;
print $cgiobject->start_html(-title=>'Search form',-bgcolor=>'white');
print "<H2>$greeting</H2>";
&output_form;
print $cgiobject->end_html;
The "main control" portion of code lays out the
output produced by this script. First, a standard
header is output to prepare the browser for
HTML. Next,
the start_html method of the CGI object creates
the opening HTML tags for the document; notice that we
provide two parameters, title and bgcolor,
which this method uses to set the <TITLE> tag and t
he <BODY> tag. The parameter construct
-parameter=>'value'
may look odd, but it allows for legible code, and
is why we called the use_named_parameters method early
in the script.
The CGI object supports a wide number of methods which
are used to output HTML tags, and we'll see several more
shortly. By and large, these methods simply make writing
HTML more convenient, but you can certainly opt to output
literal HTML if you like, as well, as seen in the next
line where we output "<H2>$greeting</H2>".
The output_form subroutine will do the dirty work
of creating the form fields on-the-fly, incorporating
the settings which were stored in the cookie (if any).
Once done, we close the HTML output via the end_html
call.
sub init()
#initialize form field values
{ $search_term="Enter search term here.";
$result_style="brief";
$result_perpage=50;
}
If there was no cookie present, the init subroutine
sets some default values for our three settings:
the search term, the result style, and the results per page.
Again, remember that this is a fictitious search engine
but these seem like realistic settings one might use.
sub output_form()
#construct and output the form HTML
{ $theform=$cgiobject->startform(-name=>'searchform',
-method=>'get',
-action=>'/cgi-bin/dosearch.cgi');
#create text input field
$theform.="Search: ";
$theform.=$cgiobject->textfield(-name=>'search_term',
-size=>30,
-default=>$search_term);
#create two radio buttons
$theform.="<BR>Results type:";
$theform.=$cgiobject->radio_group(-name=>'result_style',
-values=>["brief","verbose"],
-default=>$result_style);
#create select box
$theform.="<BR>Results per page:<BR>";
$theform.=$cgiobject->scrolling_list(-name=>'result_perpage',
-values=>[25,50,100],
-default=>$result_perpage,
-size=>3,
-multiple=>'false');
#create submit and reset buttons
$theform.="<BR><BR>";
$theform.=$cgiobject->submit(-label=>'Submit');
$theform.=$cgiobject->reset(-label=>'Clear');
$theform.=$cgiobject->endform;
print $theform
}
This output_form subroutine may appear complex
but it's rather simple, in fact. Sequentially, we output
each type of form element to appear on the page, using
various methods of the CGI object. Each method takes certain
parameters depending on the type of form field. These
parameters roughly coincide with the attributes one would
define in writing these forms in HTML. Notice that we
can use Perl variables in creating these forms -- thus, the
text field's default value is $search_term,
while the default selected radio button is that named
in $result_style. Lastly, in the scrolling list
field which represents "results per page", the
variable $result_perpage defines which item is
initially selected.
It becomes clear, then, how setting the values to
these three variables affects how the form is drawn to the
page -- which options are selected. Thus, storing these
values inside a cookie between sessions lets us redraw
the form while maintaining state.
sub crumble_cookie()
#parses cookie data into variables and values
{ @vars=split(/\|/,$cookie_data);
foreach $var (@vars)
{ @pair=split(/=/,$var);
$evalstr='$'.$pair[0].'=';
$evalstr.="\"$pair[1]\"";
eval ($evalstr);
}
}
Finally, we see the crucial crumble_cookie subroutine.
Because a cookie is simply a chunk of data, the
structure of that data is arbitrary. As we'll see in
the companion script, where we create the cookie, we've come
up with a simple scheme for packing three variables and
values into the cookie data, in the form:
variable1=value1|variable2=value2|variable3=value3
Simply, the equal sign separates the variable name from
the value and the vertical bar acts as a delimiter.
When the cookie is retrieved, the variable $cookie_data
may contain a value such as:
search_term=green|result_style=brief|result_perpage=50
Thus the role of crumble_cookie is to parse this
string of data into its component variables and values,
and make the assignments between them. First, the value
of $cookie_data is split, at each instance of the
vertical bar (|), into an array @vars. This will
result in each array item containing the variable=value
pair. We then take each array item and further split it
across the equal sign; in doing so, we build a string,
assigned to $evalstr, such as
$search_term="green"
The eval() function in Perl executes a string as
if a Perl statement; thus, to eval the string above
performs the assignment of "green" to the
variable $search_term. Viola.
Once complete, crumble_cookie has set the three
variables with their stored values, and thus when the
form is output by output_form the values used are
those "remembered" from the previous session.
Cookies: Our Misunderstood Friends
The Perl You Need to Know
Cookie Example: Part II -- Creating the Cookie
|