Digital Media

Moshell - Spring 99

Lecture 4: Your Basic CGI Script

This chapter will take us through Chapters 3-11 of the CGI book, and prepare you to undertake your first Lab assignment.

These chapters don't have a whole lot of information in them, per chapter. We'll hit a few of the high spots in Chapters 3 and 4, in the form of queries.

Query 4.1: How do you make a radio button come up as the default (that is, the one button in a set which is initially black?)

Query 4.2: What is an environment variable? Whose environment (client or server) is it in? Is it stored in a scalar, an element of an array, or an element of a hash? Why?

Query 4.3: What information is contained in $ENV{"HTTP_REFERER"}?
 

Some Essential Perl Capabilities

Let's go out of order here. The text actually introduces a script in Chapter 5 that is full of stuff the reader hasn't encountered yet, but I prefer to lead you through the HOW before we do the WHAT.

Chapters 5, 6 teach basic things about assignment statements and arithmetic operators. Zoom through them, please.

Chapter 7 describes how to load up an array with elements in a single assignment statment, like

@weekdays=("Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday");

Once this is done, $days[0] returns "Monday" etc.

It's referred to as $ rather than @ because we're talking about a $ingle location.

You don't have to declare arrays; you just use them. They automatically grow as needed. Sounds like a hash, doesn't it? Suspicious, huh?

An example, shortened from the one on page 86.The assumption is that the incoming data looks like

3,23,44,55,66,77

#!/usr/local/bin/perl

require "subparseform.lib";    # Some foreshadowing here. Magic to get the data in.
&Parse_Form;                    # Do the magic to put the form into %formdata.

@numbers= split (/,/,$formdata{"number"});
                                        # Get a string from an element of formdata at the key 'number'.
                                        # Split it wherever a acomma appears (/,/) into separate elements of 'numbers'

print "Content-type: text/html\n\n";

print "The numbers you entered were:";

foreach $number (@numbers)
{
    print "<LI> $number";
}

So you see how split works. Also how foreach works.

Query 4.4: Read Chapter 7.  Now write a code fragment which prints out the last element of an array named @tomicpower - however long it might be.

Chapter 8 - Conditional Stuff

Freeze dried and shrunk: Pay attention to the difference between == and eq.

Cultural item: PERL supports a wierd little construct that you will see in other people's scripts. I doubt you'll see it in YOUR scripts unless you're wierd, too. But who knows?

That wierd little item is

unless ($food eq "spinach")
{
print "Why didn't you order spinach?";
}

It only does the following code if the tested phrase is false. unless($something) is just like if (!$something).

while and until are repeaters which repeat their controlled code until the control becomes false, or true respectively.

do .... while ($something) executes the block once before checking the while.

for ($i=1; $i<10; $i++) works just like it does in C.
 

Procedures ("subroutines") have a simple syntax.
 

sub fixit
{
    local ($fixup);
    $fixup = $_[0]." is fixed.";
    return $fixup;
}
The input parameters of a subroutine are referred to as $_[0], $_[1], etc. If this line occurred:
    print &fixit("Michael");
the result would be
    Michael is fixed.
If you ever see a Perl subroutine with no RETURN, but which nevertheless returns a value, it's using an "implicit return". The last value assigned to a variable inside the routine, wherever that was, is the value returned by the subroutine. It's much clearer to use RETURN, but Perl programmers sometimes love to make tight, cryptic code.
 
 

The Hello World Perl Script


Here's my commented version of a simple program which uses a subroutine called parse_form_data. You can cut-and-paste this program right out of this document and go execute it (if you remember to set permissions properly, by chmod 755 myprogram.pl and if your program is named myprogram.pl.)

#!/usr/local/bin/perl

print "Content-type: text/html\n\n";
# I like to get that out of the way, first thing.....

sub parse_form_data    # This is a subroutine version of the mysterious red script on Page 66.
{
        # This subroutine brings into being a hash named %FORM_DATA and
        # populates it with the data from your form. What more could one want?
        #

local ($request_method,                # will separate GETS from POSTS
                $query_string,                    # will store our main input
                @pairs,                               # will store results of stage one of nibbling
                $pair,                                # one piece (pair) of stage one of the nibbling
                $key, $value);                    # the pair, at stage two of the nibbling process

#####################
# Part 1: Get data to work on
#####################

  $request_method=$ENV{'REQUEST_METHOD'};    # environment:
                                                                        # How did data come to us?
    if ($request_method eq "GET")                  # Note use of 'eq' for string match
        {
            $query_string = $ENV{'QUERY_STRING'}; # Notice $ENV is associative?
        }
    elsif ($request_method eq "POST")            # The only other legal option
        {
            read (STDIN, $query_string, $ENV{'CONTENT_LENGTH'});
        }
    else
        {
            print "Content-type: text/html\n\n";
            print "<P>Use Post or Get, please!\n";
        }

#######################
# Part 2: Munch data into key value pairs, in two steps
#######################
    # Query string looks like key1=value1&key2=value2&key3=value3

    @pairs = split (/&/, $query_string);

            # @pairs now contains data like this:
            #                    key1=value1
            #                    key2=value2
            #                    key3=value3  etc
            # These are in locations $pairs[0], $pairs[1], etc.

    foreach $pair (@pairs)    # Loop across the array
        {
            ($key, $value) = split (/=/, $pair)
                # $key now contains "key1", and $value contains "value1"

           $value =~ tr/+/ /;    # Translate all the plusses in $value into blanks.
                                        # This is because the browser sent + wherever it found blanks.
                                       # But how did they send +? As a hex sequence. The next bit of code
                                      # Translates special characters like + back into their original form.

            $value =~ s/%([\dA-Fa-f][\dA-Fa-f])/pack ("C", hex ($1))/eg;

                    # $value now has all its embedded hexadecimal stuff (like %4F)
                    # Translated into the corresponding characters (like "!")
                    # The above string translation command takes 3 days to understand.

            $value =~s/<!--(.|\n)*-->//g;

                    # This is a security precaution to eliminate "Server side includes". Understanding
                    # this command takes FOUR days. We'll get to it.

######################
# Now, put key-value pairs into the associative array!
######################

          # Here's the simple version, for teaching purposes (it's just a comment.)

            # $FORM_DATA{$key} = $value; # Note {curly brackets <- associative}

         # Here's the more complex version that's in the text. It supposedly manages
         # Cases where two or more values arrive for the same key.
         # I BELIEVE THIS CODE TO BE WRONG. See below.

            if (defined ($FORM_DATA{$key})    # Did one such already arrive?
            {
                $FORM_DATA{$key} .= ", $value";
            }
            else
            {
                  $FORM_DATA{$key} = $value; # as before
            }

        }    # END of the foreach
$dummy=1;    # Forces a return value of 1, if this is used as a function.
}    # END of parse_form_data

###########################
#
# MAIN Program
#
###########################

 &parse_form_data;

 print "And the lucky winner is .... $FORM{'winner'} \n";

# END of the Main Program
 

AND FINALLY the HTML Thereof:


Here's the HTML that I used to test the above program:

<HTML>

<HEAD>
<TITLE>CAP4020 Example 1</TITLE>
</HEAD>

<BODY>
<form METHOD=POST ACTION="http://www.regmaster.com/rm-bin/teach/hello.pl">
<! I hope it's obvious that you must change the above line to the location of your server!>

<h3> Type your name, or else!
</h3>
<input name="winner" size=25 maxlength=25 >
<input type="submit" value="GO FOR IT">

</BODY>

</HTML>

Query 4.5: It's time, folks. Put the "hello world" application in place on your UCF server, and execute it. Then modify it so that it has THREE input fields, and echoes them back like we did with the "winner".

You can test my script example by accessing it where I've parked it at

www.regmaster.com/hello.html.

While you are there, you are welcome to look around the site (just access www.regmaster.com. You will of course automatically be directed to index.html). Just please don't actually register for any conferences! You may try out the registration systems, because they don't actually record any data until you go the final step where it says "Submit your order".

Don't do that.

Now we will move right along and discuss Lab 1.
 

Back to previous lecture
Forward to next lecture
Back to the Index
Back to the Syllabus