Приглашаем посетить
Дружинин (druzhinin.lit-info.ru)

15.3 Basic CGI applications with Perl

Table of Contents

Previous Next

15.3 Basic CGI applications with Perl

15.3.1 Collect and store data online

One of the practical applications of using server storage is to collect user information online such as comments and consumer opinions. These data may be used later for statistical analysis and form one of the basic tools of marketing research.

Our next example is a page to collect users' opinions on their favorite browsers and operating systems. This page first displays an XHTML document ex15-09.htm for the user to fill. Once the form has been filled and the Send button pressed, the form will be submitted to the Perl script program ex15-09.pl for processing. After sending an acknowledgment back to the user, the Perl script opens a data file and appends the data to it.

The interface part of the example is listed below:



Example: ex15-09.htm - Collect And Store Data Online

 1:  <?xml version="1.0" encoding="iso-8859-1"?>
 2:  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 3:      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 4:  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 5:  <style>
 6:    .styleSt{width:320px;height:35px;background:#aaffaa;font-family:arial;
 7:             font-weight:bold;font-size:14pt;color:#880000}
 8:    .tableSt{font-size:14pt;font-weight:bold;text-align:left}</style>
 9:  <head><title>Collecting Data Online  ex15-09.htm</title></head>
10:  <body style="background:#000088;font-family:arial;color:#ffff00">
11:
12:  <form action="ex15-09.pl" method="post">
13:  <table class="tableSt" style="position:absolute;top:30px;left:160px">
14:   <tr><td colspan="2" style="text-align:center;font-size:22pt">Your
15:        Favorite Browsers And<br />Operating Systems<br /><br /></td></tr>
16:   <tr><td>Name: </td>
17:       <td><input type="text" value="" class="styleSt" name="nameId"
18:             style="color:#000000;background:#dddddd"/></td></tr>
19:   <tr><td>Email Address:</td>
20:       <td><input type="text" value="" class="styleSt" name="emailId"
21:             style="color:#000000;background:#dddddd"/></td></tr>
22:  </table>
23:  <table class="tableSt" style="position:absolute;top:230px;left:160px">
24:   <tr><td>Internet Explorer 6.x: &nbsp;&nbsp;</td>
25:       <td><input type="radio" class="styleSt" id="brId" name="brId"
26:            style="width:40px" value="Internet Explorer 6.x" /></td></tr>
27:   <tr><td>Internet Explorer 5.x: &nbsp;&nbsp;</td>
28:       <td><input type="radio" class="styleSt" id="brId" name="brId"
29:            style="width:40px" value="Internet Explorer 5.x" /></td></tr>
30:   <tr><td>Netscape 6.x: &nbsp;&nbsp;</td>
31:       <td><input type="radio" class="styleSt" id="brId" name="brId"
32:            style="width:40px" value="Netscape 6.x" /></td></tr>
33:   <tr><td>Opera: &nbsp;&nbsp;</td>
34:       <td><input type="radio" class="styleSt" id="brId" name="brId"
35:            style="width:40px" value="Opera" /></td></tr>
36:   <tr><td>Netscape Nevigator: &nbsp;&nbsp;</td>
37:       <td><input type="radio" class="styleSt" id="brId" name="brId"
38:            style="width:40px" value="Netscape Nevigator" /></td></tr>
39:   <tr><td>Others: &nbsp;&nbsp;</td>
40:       <td><input type="radio" class="styleSt" id="brId" name="brId"
41:            style="width:40px" value="Others" /></td></tr>
42:  </table>
43:  <table class="tableSt" style="position:absolute;top:230px;left:450px">
44:   <tr><td>Windows XP: &nbsp;&nbsp;</td>
45:       <td><input type="radio" class="styleSt" id="osId" name="osId"
46:            style="width:40px" value="Windows XP" /></td></tr>
47:   <tr><td>Windows 2000: &nbsp;&nbsp;</td>
48:       <td><input type="radio" class="styleSt" id="osId" name="osId"
49:            style="width:40px" value="Windows 2000" /></td></tr>
50:   <tr><td>Windows 9.x: &nbsp;&nbsp;</td>
51:       <td><input type="radio" class="styleSt" id="osId" name="osId"
52:            style="width:40px" value="Windows 9.x" /></td></tr>
53:   <tr><td>Windows NT: &nbsp;&nbsp;</td>
54:       <td><input type="radio" class="styleSt" id="osId" name="osId"
55:            style="width:40px" value="Windows NT" /></td></tr>
56:   <tr><td>Linux: &nbsp;&nbsp;</td>
57:       <td><input type="radio" class="styleSt" id="osId" name="osId"
58:            style="width:40px" value="Linux" /></td></tr>
59:   <tr><td>Mac OS: &nbsp;&nbsp;</td>
60:       <td><input type="radio" class="styleSt" id="osId" name="osId"
61:            style="width:40px" value="Mac Os" /></td></tr>
62:  </table>
63:  <table class="tableSt" style="position:absolute;top:500px;left:210px"><tr>
64:   <td><input type="reset" class="styleSt" style="width:200px;
65:     background:#aaaaaa" value="Reset" /></td>
66:   <td><input type="submit" class="styleSt" value="Send"
67:     style="width:200px;background:#aaaaaa" /></td></tr>
68:  </table>
69:  </form>
70:  </body></html>

This XHTML page is a form application containing four tables. The first table defined in lines 1322 is to get the user's name and email address. The second table in lines 2342 generates a series of radio boxes to get the user's favorite browser. The third table in lines 4362 again generates a series of radio boxes to obtain the user's favorite operating system. The last table (lines 6368) in this document contains two buttons, Send and Reset. A screen shot of this interface is shown in Fig. 15.8.

Figure 15.8. ex15-09.p1

graphics/15fig08.jpg


Once the form is filled and the Send button is pressed, the form will be sent to the Perl script ex15-09.pl. The coding of this script is listed below:



Listing: ex15-04.txt - Perl Script ex15-09.pl For ex15-09.htm

 1: #!usr/bin/perl
 2: use CGI qw (:standard);
 3: print ("Content-type:text/html\n\n");
 4:
 5: $nameV = param("nameId");
 6: $emailV = param("emailId");
 7: $brV = param("brId");
 8: $osV = param("osId");
 9:
10: print << "mypage";
11:  <?xml version="1.0" encoding="iso-8859-1"?>
12:  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
13:  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
14:  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
15:  <head><title>Example: ex15-09.pl</title></head>
16:  <style>.txtSt{font-size:14pt;color:#ffff00;font-family:arial}</style>
17:
18:  <body style="background:#000088" class="txtSt">
19:   Thank You For Returning the Questionnaire<br /><br />
20:   Your information has been added into our database<br /><br />
21:
22:  <table cellspacing="15" class="txtSt">
23:   <tr><td>Name</td><td>Email</td><td>Browser</td><td>O.S.</td></tr>
24:   <tr><td>$nameV</td><td>$emailV</td><td>$brV</td><td>$osV</td></tr>
25:  </table><br />
26:  www.pwt-ex.com
27: mypage
28:
29: open(filehandle,">>user.dat")
30:  or die("Cannot Open Data File.. Error");
31: print (filehandle "$nameV,$emailV,$brV,$osV\n");
32: close(filehandle)

First, the param() function is used to capture the submitted values from the form. The values of user name, email address, browser, and operating system are stored in the variables $nameV, $emailV, $brV, and $osV respectively. The next step is to return an acknowledgment in XHTML as illustrated in lines 1027. After the acknowledgment, the script opens a data file called user.dat for appending (line 29). The single print statement in line 31 would append all the data to the end of the file. The file is closed when all operations are completed. Some screen shots are shown in Figs 15.9 and 15.10.

Figure 15.9. Returning an XHTML page

graphics/15fig09.jpg


Figure 15.10. Contents of user.dat

graphics/15fig10.gif


15.3.2 Verifying user name and password

Verifying user name and password is a common security practice on the Internet. In normal circumstances, all the user names and their corresponding passwords are stored in a file on the server. Therefore, to verify user name and password for a particular user on the Internet, a CGI application is required. Since we don't have encryption at this moment, the implementation of password checking is relatively simple. Suppose you have password file called password.txt containing all the user names and passwords. To check a password for a particular user it is necessary to read this file and perform the comparison. Consider the interface part of this example:



Example: ex15-10.htm - Verifying Username And Password

 1: <?xml version="1.0" encoding="iso-8859-1"?>
 2: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 3:     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 4: <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 5: <head><title>Username and Password  ex15-10.htm </title></head>
 6: <style>
 7:   .butSt{background-color:#aaffaa;font-family:arial;font-weight:bold;
 8:      font-size:18pt;color:#880000;width:250px;height:35px}
 9:   .txtSt{font-family:arial;font-weight:bold; text-align:left;
10:      font-size:18pt;color:#ffff00}</style>
11: <body style="background:#000088">
12: <form action="ex15-10.pl" method="post">
13: <table style="position:absolute;left:60px;top:50px" class="txtSt">
14:  <tr><td colspan="2" style="text-align:center">
15:      Enter Your Username and<br /> Password Below<br /><br/></td></tr>
16:  <tr><td>Name:</td><td><input type="text"
17:          name="userId" id="userId" class="butSt" ></td></tr>
18:  <tr><td>Password:</td><td><input type="password"
19:          name="passId" id="passId" class="butSt"></td></tr>
20:  <tr><td><input type="submit" class="butSt" value="O.K."
21:       style="width:150px;background:#dddddd"></td></tr>
22: </table>
23: </form>
24: </body></html>

This is a simple interface page with two input fields. The password field in line 18 is declared with type="password" so that the typed characters will be covered by asterisks. A screen shot of this page is shown in Fig. 15.11.

Figure 15.11. ex15-10.p1

graphics/15fig11.jpg


When the user name and password are filled and the O.K. button is clicked, the form is sent to the Perl script ex15-10.pl for processing (Fig. 5.12). The program code of the script is listed as follows:



Example: ex15-10.pl - The Perl Script For ex1510.htm

 1: #!usr/bin/perl
 2: use CGI qw (:standard);
 3: my $username = param(userId);
 4: my $password = param(passId);
 5:
 6: print "Content-type:text/html\n\n";
 7: print << "mypage";
 8:  <?xml version="1.0" encoding="iso-8859-1"?>
 9:  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
10:  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
11:  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
12:  <head><title>Example: ex15-10.pl</title></head>
13:  <style>.txtSt{font-size:18pt;color:#ffff00;font-family:arial}</style>
14:  <body style="background:#000088;font-weight:bold" class="txtSt">
15: mypage
16:
17: open(filehandle, "password.txt") or
18:  die "The File could not be opened .. Error.";
19:
20: while(my $st = <filehandle>)
21: {
22:    $st =~ s/\n//g;
23:    ($name, $pass) = split(/,/, $st);
24:
25:    if($name eq "$username")
26:    {
27:      $userF = 1;
28:      if ($pass eq "$password")
29:      {
30:         $passwordF = 1;
31:      }
32:    }
33:  }
34: close(filehandle);
35:
36: if ($userF && $passwordF)
37: {
38:   print ("Thank you -- $username <br /> Access Granted !!
39:           <br />Enjoy Your Visit.");
40: }
41: elsif ($userF && !$passwordF)
42: {
43:   print ("Sorry, Wrong Password !!");
44: }
45: else
46: {
47:   print ("Sorry, Access Denied !!");
48: }
49: print "</body></html>";

Figure 15.12. Passed accepted

graphics/15fig12.jpg


The param() functions used in lines 3 and 4 get the user name and password from the XHTML form and store them in variables $username and $password. After the document header in lines 515, the script opens the password file password.txt and processes the file with the following while-loop:



while(my $st = <filehandle>)
{
   $st =~ s/\n//g;
   ($name, $pass) = split(/,/, $st);
   if($name eq "$username")
   {
     $userF = 1;
     if ($pass eq "$password")
     {
        $passwordF = 1;
     }
   }
}

Inside the while-loop, each line of the file is read into the string $st. Since the string $st may contain a line break "\n" at the end, a substitution is required to remove it. The string $st is then split into $name and $pass containing the user name and password from the file. If the variable $name equals the user name from the user input, $userF is set to be true to indicate that the user name is matched. If the password is matched, the variable $passwordF is set to true.

The remaining part of the script is easy to read. Basically, if both user name and password are matched, a message is displayed to grant access. Some readers may want to use the following statement to redirect the browser to another new page:



print redirect('http://www.pwt-ex.com');

Obviously, access cannot be granted if the password is not matched. If the line break of $st is not "chopped off," you may have difficulty comparing the password.

15.3.3 Implementation of a guest book

A guest book is a common feature of many Web sites where comments are obtained from users or visitors. Visitors can write something in the guest book and share their views. Any person should be able to sign the book and view its contents at any time.

Apart from messages stored as file records on the server, a good guest book implementation should also include markup symbols for formatted display and database applications. Also a simple log file would be helpful to log all user access. The use of such a log file is common in professional programming. For example, Microsoft uses them whenever you turn on your Windows system. Our implementation of a guest book will have these features but in a much simpler form.

Consider the interface part of the example:



Example: ex15-11.htm - A Guest Book Using Perl

 1: <?xml version="1.0" encoding="iso-8859-1"?>
 2: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 3:     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 4: <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 5: <head><title> A Guest Book Using Perl  ex1511.htm </title></head>
 6: <style>
 7:  .tx01{font-size:14pt;color:#000088;font-weight:bold}
 8:  .tx02{font-family:arial;font-size:14pt;background:#ffffff;color:#000000}
 9:  .butSt{background-color:#aaffaa;font-family:arial;font-weight:bold;
10:     font-size:14pt;color:#008800;width:100px;height:30px}
11: </style>
12: <body style="background:#bbbbff;font-family:arial;color:#000088">
13: <div style="font-size:18pt;text-align:center;font-weight:bold">
14:   Please Sign Our Guest Book<br />www.pwt-ex.com
15:  <form method="post" action="ex15-11a.pl">
16:  <table class="tx01">
17:  <tr><td>From:</td>
18:    <td><input class="tx02" type="text" name="from" id="from"></td></tr>
19:
20:  <tr><td valign="top">Message:</td>
21:    <td><textarea name="message" id="message" class="tx02"
22:        rows="6" cols="40" wrap="yes"></textarea></td></tr>
23:
24:  <tr><td><input class="butSt" type="submit" value="Submit"></td>
25:    <td><input class="butSt" type="reset" value="Reset"></td></tr>
26:  </table>
27:  </form><br />
28:  <a class="butSt" style="width:405px;color:#880000"
29:    href="ex15-11b.pl">
30:     Please Click Me To Read Guest Book</a>
31: </div>
32: </body>
33: </html>

This page contains the following features:

  • A "From" field for the user to type in his or her name.

  • A text area so the user can write something in the guest book.

  • A Submit and a Reset button.

  • An anchor element to view the contents of the guest book.

A screen shot of this interface is shown in Fig. 15.13.

Figure 15.13. ex15-11.htm

graphics/15fig13.jpg


For readability and clarity, the program code of this example is split into two parts. The first part is a Perl script ex15-11a.pl to handle all data processes once the user submits the form. The second part is also a Perl script to handle the display of the guest book contents.

For most guest books, one of the immediate features is to send a so-called "Thank you" page back to the user. The first part of ex15-11a.pl does just that and is listed below:



Example: ex15-11a.pl - The Perl Script For ex15-11.htm (Part One)

 1: #! /usr/bin/perl
 2: use CGI qw( :standard );
 3:
 4: my $from = param( "from" );
 5: my $message = param( "message" );
 6: my $timeV = scalar(localtime());
 7: print "Content-type:text/html\n\n";
 8:
 9: print << "mypage";
10:  <?xml version="1.0" encoding="iso-8859-1"?>
11:  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
12:     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
13:  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
14:  <head><title>Example  ex15-11a.pl </title></head>
15:  <body style="background:#000088">
16:  <div style="font-family:arial;font-size:18pt;color:#ffff00">
17:   Thank you -- $from <br /><br />
18:   Your Comment <br />
19:   <img src="line1.gif" height="6" width="400" /><br /><br/>
20:    $message <br/><br />
21:   <img src="line1.gif" height="6" width="400" /><br />
22:   Has Been Added Into Our Guest Book.<br /> www.pwt-ex.com
23:  </div></body></html>
24: mypage
25:

This Perl script gets the user name and guest book message from the interface with the param() function. Lines 924 use that information to build a simple "Thank you" page for sending back to the user. A screen shot of the page generated by this Perl script is shown in Fig. 15.14.

Figure 15.14. A feedback page from guest book

graphics/15fig14.jpg


The second part of ex15-11a.pl below is more interesting:



Listing: Continuation Of The Perl Script ex15-11a.pl (Part Two)

26: open(logfile,">>log.dat")
27:  or die("Cannot Open Log File.. Error");
28:
29: print logfile "user $from access guest book at -- $timeV";
30: print logfile `cp guestbk.dat temp.dat`;
31:
32: open(filehandle,">guestbk.dat")
33:  or die("Cannot Open Data File.. Error");
34: print (filehandle " #!! #l# $message #l# #l# \n $from  $timeV #l# \n
35: =============================================!!#\n");
36: close(filehandle);
37:
38: print logfile `cat temp.dat >> guestbk.dat`;

In this script, a log file called log.dat is opened in lines 2627. This file can be used to log any message that you want to have. For our simple implementation, the first thing we want to do with this file is to log the user name and time (line 29).

Another feature of our guest book is that the latest submitted message will appear at the top of the guest book file guestbk.dat. A simple way to do this is to

  • copy the guest book file guestbk.dat to a temporary file called temp.dat;

  • discard the contents of the guest book file and write the new message into it;

  • append the contents of the temporary file temp.dat to the guest book file.

In terms of Perl programming, the tasks above can be accomplished by



print `cp guestbk.dat temp.dat`;
  open(filehandle,">guestbk.dat");
  print(filehandle, " XXXXX ");
print `cat >> guestbk.dat temp.dat`;

If you are using Microsoft systems, you may need to use the copy command instead of cp above and the type command instead of cat.

For most operating system environments, copying files from one place to another may not be totally safe. You should embed the log file handle into an operation such as (line 30)



print logfile `cp guestbk.dat temp.dat`;

Any message from the file operation, whether successful or not, will be redirected to the log file so that you can have a check afterwards.

It is almost certain that the contents of the guest book will be read and displayed by a browser. The messages may be better stored as elements of an XHTML table. For example, if $from="Johnsmith" and $message="Good To See This Site Up and Running", the print statement in lines 3435 will generate the following record in the guest book file guestbk.dat:



#!! #l# Good To See This Site Up and Running #l# #l#
Johnsmith  Fri Mar 22 23:22:04 2002 #l#
=============================================!!#

If you perform the symbol substitutions



#!! replace by <tr><td>
#l# replace by <br />
!!# replace by </td></tr>

the record in guestbk.dat above turns out to be



<tr><td> <br /> Good To See This Site Up and Running <br /><br />
Johnsmith  Fri Mar 22 23:22:04 2002 <br />
=============================================</td></tr>

This is part of an XHTML table element and can be easily displayed by a browser. The demonstration here concentrates on ideas. It is a very simple case for formatted output. To see how the records in the guest book are displayed in a browser, consider the following Perl script:



Example: ex15-11b.pl - The Perl Script For ex1511.htm

 1: #! /usr/bin/perl
 2: print "Content-type:text/html\n\n";
 3:
 4: print << "mypage";
 5:  <?xml version="1.0" encoding="iso-8859-1"?>
 6:  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 7:     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 8:  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 9:  <head><title>Example  ex15-11b.pl </title></head>
10:  <body style="background:#000088">
11:  <div style="font-family:arial;font-size:18pt;color:#00ff00;
12:    text-align:center">Guest Book Message<br />
13:    ==================</div><br />
14:
15: <div style="text-align:center">
16: <table style="font-family:arial;font-size:14pt;color:#ffff00;width:400px">
17: mypage
18:
19: open (infile,"<guestbk.dat")
20:    or die("Cannot Open File For Reading.. Error");
21: while (my $st = <infile>)
22: {
23:   $st =~ s/\n//g;
24:   $st =~ s/(#!!)/<tr><td>/g;
25:   $st =~ s/(!!#)/<\/td><\/tr>/g;
26:   $st =~ s/(#l#)/<br \/>/g;
27:   print("$st");
28: }
29: close(infile);
30:
31: print " </table></div></body></html>";

When the underlined text "Please Click Me To Read Guest Book" is clicked (see line 30 in ex15-11.htm), this script is executed. After the declaration of an XHTML table in line 16, a while-loop is used to read the entire guest book file. For each line of the file, a series of substitutions are performed in lines 2326 to make sure that the messages are in the correct XHTML table format. After displaying all records in the file, the file is closed and the XHTML document is terminated by executing the statement in line 31. A screen shot of the display is shown in Fig. 15.15.

Figure 15.15. Displaying the record

graphics/15fig15.jpg


Now you have some basic knowledge and experience of CGI techniques with Perl script, it is time to consider some practical applications.

    Table of Contents

    Previous Next