DekGenius.com
[ Team LiB ] Previous Section Next Section

Recipe 8.6 Reading Form Parameters

Problem

You want your CGI program to read values from forms for use in your program.

Solution

First, look at an example in Perl, which uses the popular CGI.pm module:

#!/usr/bin/perl
use CGI;
use strict;
use warnings;

my $query = CGI->new;

# Load the various form parameters
my $name = $form->param("name");

# Multi-value select lists will return a list
my @foods = $form->param("favorite_foods");

# Output useful stuff
print "Content-type: text/html\n\n";
print "Name: " . $form->{name} . "n";
print "Favorite foods: <ul>";
foreach my $food (@foods) {
    print "<li>$food</li>";
}
print "</ul>\n";

Next, look at the same program in C, which uses the cgic C library:

#include "cgic.h"
/* Boutell.com's cgic library */

int cgiMain(  ) {
        char name[100];

        /* Send content type */
        cgiHeaderContentType("text/html");

        /* Load a particular variable */
        cgiFormStringNoNewlines("name", name, 100);
        fprintf(cgiOut, "Name: ");
        cgiHtmlEscape(name);

        return 0;
}

For this example, you will also need a Makefile, which looks something like this:

CFLAGS=-g -Wall
CC=gcc
AR=ar
LIBS=-L./ -lcgic

libcgic.a: cgic.o cgic.h
        rm -f libcgic.a
        $(AR) rc libcgic.a cgic.o

example.cgi: example.o libcgic.a
        gcc example.o -o example.cgi ${LIBS}

Discussion

The exact solution to this will vary from one programming language to another, and so examples are given here in two languages. Note that each of these examples uses an external library to do the actual parsing of the form content. This is important, because it is easy to parse forms incorrectly. By using one of these libraries, you ensure that all of the form-encoded characters are correctly converted to usable values, and then there's the simple matter of code readability and simplicity. It's almost always better to utilize an existing library than to reimplement functionality yourself.

The Perl example uses Lincoln Stein's CGI.pm module, which is a standard part of the Perl distribution and will be installed if you have Perl installed. The library is loaded using the use keyword and is used via the object-oriented (OO) interface.

The param function returns the value of a given form field. When called with no arguments, params( ) returns a list of the form field names. When called with the name of a multivalue select form field, it will return a list of the selected values. This is illustrated in the example for a field named favorite_foods.

The example in C uses the cgic C library, which is available from http://boutell.com/. You will need to acquire this library and install it in order to compile the aforementioned code. The Makefile provided is to assist in building the source code into a binary file that you can run. Type make example.cgi to start the compile. Note that if you are doing this on Windows, you will probably want to replace .cgi with .exe in the example Makefile.

In either case, an HTML form pointed at this CGI program, containing a form field named name, will result in the value typed in that field being displayed in the browser. The necessary HTML to test these programs is as follows:

<html><head>
    <title>Example CGI</title>
</head>

<body>

    Form:

    <form action="/cgi-bin/example.cgi" method="POST">
    Name: <input name="name">
    <br />
    <input type="submit">
    </form>

</body>
</html>

The examples given in this recipe each use CGI libraries, or modules, for the actual functionality of parsing the HTML form contents. While many CGI tutorials on the Web show you how to do the form parsing yourself, we don't recommend it. One of the great virtues of a programmer is laziness, and using modules, rather than reinventing the wheel, is one of the most important manifestations of laziness. And it makes good sense, too, since these modules tend to get it right. It's very easy to parse form contents incorrectly, winding up with data that has been translated from the form encoding incompletely or just plain wrong. These modules have been developed over a number of years, extensively tested, and are much more likely to handle the various cases that you have not thought about.

Additionally, modules handle file uploads, multiple select lists, reading and setting cookies, returning correctly formatted error messages to the browser, and a variety of other functions that you might overlook if you were to attempt to do this yourself. Furthermore, in the spirit of good programming technique, reusing existing code saves you time and tends to prevent errors.

See Also

    [ Team LiB ] Previous Section Next Section