Since the same script puts up a form that asks questions and also
retrieves the answers to those questions, we need to be able to tell
in which phase of the operation we are. We do that by testing
$data
to find out whether it is full or empty. If
it is full, we find that all the data typed into the fields of the
form by the user are there, with the fields separated by
&
. For instance, if the user had typed
“Anne” into the first-name box and
“Smith” into the surname box, this
string would arrive:
xname=Anne&sname=Smith
or, if the browser is being very correct:
xname=Anne;sname=Smith
We have to dissect it to answer the customer’s question, but this can be a bit puzzling. Not only is everything crumpled together, various characters are encoded. For instance, if the user had typed “&” as part of his response, e.g., “Smith&Jones”, it would appear as “Smith%26Jones”. You will have noticed that “26” is the ASCII code in hexadecimal for “&”. This is called URL encoding and is documented in the HTTP RFC. “Space” comes across as “+” or possibly “%20”. For the moment we ignore this problem. Later on, when you are writing real applications, you would probably use the “unescape” function from CGI.pm to translate these characters.
The strategy for dealing with this stuff is to:
Split on either “&” or “;” to get the fields
Split on “=” to separate the field name and content
(Ultimately, when you get around to using it) use
CGI::unescape($content)
, the content to get rid of
URL encoding
See the first few lines of the following subroutine
get_name()
. This is the script
.../cgi-bin/script2_html, which asks questions
and gets the answers. There are commented out debugging lines
scattered through the script, such as:
#print "in get_name: ARGS: @args, DATA: $data<BR>";
Put these in to see what is happening, then turn them off when things work. You may like to leave them in to help with debugging problems later on.
Another point of style: many published Perl programs use
$dbh
for the database handle; we use
$dbm
:
#! /usr/local/bin/perl -wT use strict; use DBI(); use CGI; use CGI::Carp qw(fatalsToBrowser); my ($data,@args); $data=<>; if($data) { &get_name($data); } elsif($ENV{'PATH_INFO'} eq "/whole_database") { $data="xname=%&sname=%"; &get_name(); } else { &ask_question; } print "</BODY></HTML>"; sub ask_question { &print_header("ask_question"); print qq(<A HREF="/cgi-bin/script2_html/whole_database"> Click here to see the whole database</A> <BR><FORM METHOD='POST' ACTION='/cgi-bin/script2_html/name'> Enter a first name <INPUT TYPE='TEXT' NAME='xname' SIZE=20><BR> and or a second name <INPUT TYPE='TEXT' NAME='sname' SIZE=20><BR> <INPUT TYPE=SUBMIT VALUE='ENTER'>); } sub print_header { print qq(content-type: text/html\n\n <HTML><HEAD><TITLE>$_[0]</TITLE></HEAD><BODY>); } sub get_name { my ($t,@val,$ref, $mesg,$dbm,$query,$xname,$sname,$sth,$rows); &print_header("get_name"); #print "in get_name: ARGS: @args, DATA: $data<BR>"; $xname="%"; $sname="%"; @args=split(/&/,$data); foreach $t (@args) { @val=split(/=/,$t); if($val[0] eq "xname") { $xname=$val[1] if($val[1]); } elsif($val[0] eq "sname") { $sname=$val[1] if($val[1]); } } # open a database $dbm=DBI->connect("DBI:mysql:database=people;host=localhost",'webserv') or die "didn't connect to people"; # get it back $query=qq(select xname, sname from people where xname like ? and sname like ?); $sth=$dbm->prepare($query) or die "failed to prepare $query: $!"; #print "$xname, $sname: $query<BR>"; # $! is the Perl variable for the current system error message $sth->execute($xname,$sname) or die "failed to execute $dbm->errstr()<BR>"; $rows=$sth->rows; #print "$rows: $rows $query<BR>"; if($sname eq "%" && $xname eq "%") { print qq(<table border=1 width=70%><caption><h3>The Whole Database (3)</h3></ caption>); } else { print qq(<table border=1 width=70%><caption><h3>The $rows People called $xname $sname</h3></caption>); } print qq(<tr><align left><th>First name</th><th>Last name</th></tr>); while ($ref=$sth->fetchrow_hashref) { print qq(<tr align right><td>$ref->{'xname'}</td><td> $ref->{'sname'}</td></tr>); } print "</table></BODY></HTML>"; $sth->finish; # close the database connection $dbm->disconnect; }
The Config file is ...site.cgi/httpd3.conf.
User webuser Group webgroup ServerName www.butterthlies.com DocumentRoot /usr/www/APACHE3/APACHE3/site.cgi/htdocs # for scripts in .../cgi-bin /cgi-bin /usr/www/APACHE3/APACHE3/cgi-bin DirectoryIndex /cgi-bin/script2_html
Kill Apache and start it again with ./go
3
.
The previous script handles getting data to and from the user and to and from the database. It encapsulates the essentials of an active web site — whatever language it is written in. The main missing element is email — see the following section.