PerlStalker's SysAdmin Notes and Tools

- Skip Navigation- Home / Perl / Modules / CGI

Printer Friendly

Join the Blue Ribbon Online Free Speech Campaign

 

CGI.pm

Lincoln D. Stein's CGI module provides an excellent interface to the CGI protocol. CGI.pm makes generating HTML pages simple while still providing the power that is needed by some applications. By combining CGI.pm and DBI.pm, programmers can create web-based database applications easily.

Getting Input from the User

Like most CGI programs, Perl CGI programs get their input from HTML forms. A programmer can access the passed in variables by calling the `param' method of the CGI object. When called without parameters, param returns the list of parameter names. When called with the field name, param returns the value of the field.

#!/usr/bin/perl -w
# Demonstrate the use of
# CGI's param method

use CGI;
use strict;

# Create the CGI object.
# This also parses the input
my $cgi = new CGI;

# get the list of parameter names
my @param_names = $cgi->param;

# Output all of the input fields
# and their values. See $cgi->dump
# in the CGI docs for a better way
# to do this.
foreach my $name (sort @param_names)
{
    print "$name: ", $cgi->param($name), "\n";
}

Dynamic vs. Static Pages for Input

CGI.pm gives a programmer the ability to generate HTML forms "on the fly." So the question is, which is for input, dynamic or static pages? The answer is "It depends."

For pages that do not change, static pages make more sense. The web server can server the file more quickly and efficiently than the script can generate it.

There will be times, however, when you will want to create a form based on input from a previous form. The new form may be part of the results (like the 'Next Results' buttons on search engines) or be another part of the same form (think surveys here).

Static pages should be used whenever possible. However, programmers should not be afraid to use dynamic pages to get input from the user when neccissary.

#!/usr/local/bin -w
# Demonstrate creating a
# dynamic form.

# import all CGI methods
# into our namespace.
use CGI qw(:all);
use strict;

my $cgi = new CGI;

# Print the HTTP header
print header;
# Print the HTML header and body tag
print start_html
    ('-title' => 'Demo Form');
# Start the form
print start_form ('-action' => 'login.cgi',
		  '-method' => 'Post');
# Prompt for user name
print 'User: ', textfield ('-name' => 'User'), br;
# Promt for passwd
print 'Pass: ', password_field ('-name' => 'Pass');
# Print the submit button
print br, submit ('-name' => 'Log in');
# End the form
print end_form;
# end the page
print end_html;

Displaying Results

What's the point of using a database (or any program for that matter) if you are not going to show the user the fruits of his/her labor? So, we need to kick out some data. The problem then comes in making the output readable. I'll talk about the two nice ways of displaying data in the next sections.

Linear Display

The easiest way to display data is to dump it out in a line. For example, one could write one record per line to the output page. This is fast but can become hard to read.

#!/usr/local/bin/perl -w
# Demonstrate linear display
# of data.

use DBI;
use CGI qw(:all);
use strict;

my $cgi = new CGI;
my $dbh = DBI->connect(...);

my $sth = $dbh->prepare
    ("SELECT * from Table1;");
my $sth->execute or die $sth->errstr;
my @data = $sth->fetchall_arrayref;
$sth->finish;
$dbh->disconnect;

print header;
print start_html ('-title' => 'Results');
foreach my $row (@data)
{
    # Remember that $row is a list reference
    foreach my $field (@{$row})
    {
	print "$field | ";
    }
    print br;
}
print end_html;

Dynamic Tables

A nicer way to display the data is with a table. CGI.pm provides methods to create dynamic tables. There are some issues that need to be considered when building the table for the data.

First, you can't put the loops inside the method call. This means that you will need to create the strings ahead of time and then pass them in to the appropriate method.

The second inssue is one of documentation on the table methods. When a list is passed to the method, it puts every element into the single tag. However, when a list reference is passed in, every element is put in its own tag. While not a problem, it can be a great tool or a real debugging headache.

#!/usr/local/bin/perl -w
# Demonstrate dynamic tables.

use DBI;
use CGI qw(:all);
use strict;

my $cgi = new CGI;
my $dbh = DBI->connect(...);

my $sth = $dbh->prepare
    ("SELECT * from Table1;");
my $sth->execute or die $sth->errstr;
my @data = $sth->fetchall_arrayref;
$sth->finish;
$dbh->disconnect;

my @rows;
foreach my $record (@data)
{
    my $row = '';
    foreach my $field (@{ $record })
    {
	$row .= td($field);
    }
    push @rows, $row;
}

print header;
print start_html ('-title' => 'Results');
print table (Tr([@rows]));
print end_html;
Copyright © 2003-2008 Randall B. Smith
<perlstalker AT falconsroost.alamosa.co.us>