Keeping Programs Trim with CGI_Lite

This article is an introduction to a second CGI module, CGI_Lite, that is not as feature rich as CGI but is much smaller in size and therefore more efficient for use in small-scale projects.

This month, we will look at CGI_Lite, a
Perl 5 module written by Shishir Gundavaram. CGI_Lite is one of
several modules available for CGI programmers; the best known of
the bunch is CGI.pm, written by Lincoln Stein. Indeed, I have used
CGI.pm in nearly every “At the Forge” column, as well as in many
programs over the last few years, on many web sites.

While CGI.pm is useful and rich in features, it is also
large, weighing in at a hefty 153KB. On my Red Hat 4.2 system with
40MB of RAM, starting Perl 5 and loading CGI.pm uses about 2.7
percent of the physical memory—over 1MB—before I have even
allocated any data structures. On a popular Web server, it is easy
to imagine how many CGI programs running simultaneously would lead
to a heavy load, both on the CPU and on the server's memory,
leading to a significant slow-down.

There are a number of solutions to this problem, including
using a language other than Perl for CGI programs. This month,
though, we will look at another solution: CGI_Lite.pm, a module
that does less than CGI.pm but is much smaller and faster.
CGI_Lite.pm takes a mere 17KB on disk, and when loaded into memory
along with Perl 5, takes only 2.0 percent of the physical memory on
my system, about 800KB. This is still a relatively large amount of
memory, but given that invoking Perl 5 uses about 560KB, it strikes
me as a reasonable trade-off.

CGI_Lite.pm is not a panacea; it leaves out a number of
useful features that have made their way into CGI.pm over the
years. However, if your CGI programs require only a limited set of
features and you would like to keep your programs as trim as
possible, you might want to consider using CGI_Lite in at least
some of your programs.

Getting Started with CGI_Lite.pm

Before you can use CGI_Lite, you need to get a copy from CPAN
(the Comprehensive Perl Archive Network), a set of FTP and web
servers that make Perl code, documentation and utilities available
to the public for free. As of this writing, the latest version of
CGI_Lite is 1.8, meaning that you can retrieve it from the URL
http://www.perl.com/CPAN/modules/by-module/CGI/CGI_Lite-1.8.tar.gz.

If CGI_Lite has been updated by the time you read this, you
might need to change the numbers in the last part of the URL. Once
you have retrieved the module, you can unpack it with the
command:

Note that you may have to be logged in as root in order to install
CGI_Lite on your system.

Once the module is installed, you can use it in any program
by including the line:

use CGI_Lite;

at the top of your program.

Of course, including a module is the easy part—learning how
to use it can be a bit more complicated. Let's see how to use
CGI_Lite.pm by creating a simple program, one which expects to
receive a user's first name from an HTML form. When the form is
submitted, the program prints a short personalized greeting to the
user. If you are wondering why we are starting with an HTML form
and the POST method, rather than the simpler GET method, stay
tuned—it is harder than you might think.

Listing 1 is a simple HTML form, containing a single text
field called firstname, that we can use for
our test. When a user clicks on the submit button in this form, the
firstname text field is sent via the POST
method to the program called /cgi-bin/hello.pl. Listing 2 shows one
way in which we might write
hello.pl using CGI_Lite.pm.

Retrieves the HTML form elements into a hash, also
known as an “associative array”.

Uses the value of the
firstname form element to return a string to
the user.

Dissecting hello.pl

Now that we have gotten an overall picture of what is
happening in the above program, let's look at this in greater
detail, with a bit of attention to some of the differences between
CGI.pm and CGI_Lite.pm.

In CGI.pm, we can retrieve form elements using the
param method. When invoked in a
scalar context, param allows us to retrieve the value of a single
HTML form element. For example, if we have defined
$query to be an instance of CGI,
we can place the value of the firstname field
in the $firstname variable with the following
statement:

my $firstname = $query->param("firstname");

If we invoke param in an array context, then we get a list of
all form elements that were submitted to the program. For example,
if we want to put the names of all HTML form elements into the
array @names, we can do so with the following
statement:

my @names = $query->param;

We can then iterate through @names to retrieve
and print the value associated with each form element, as in:

We can accomplish this with CGI_Lite.pm, but in a slightly
different way. CGI_Lite.pm has a single method for retrieving form
elements, one which uses hashes rather than a mixture of scalars
and arrays. To retrieve form elements, we use the method
parse_form_data, which returns its
results in a hash. Retrieving individual form elements is thus a
two-step process. First we put all of the elements into the hash,
and then we retrieve the one in which we are interested:

my %FORM = parse_form_data;
my $firstname = $FORM{"firstname"};

If we want to get a list of the form elements that were sent, we
can use the keys function. Thus, to put the names of the form
elements in the array @names, we can type:

my @names = keys %FORM;

We can even get them in alphabetical order, by prefacing keys with
a call to sort:

my @names = sort keys %FORM;

We can print the names and values of all form elements by iterating
through @names and retrieving the values in
which we are interested: