Perl Basics - Part 3

OK, now we're getting to actual juicy stuff you can use with the Web.

Receiving user input from forms

Like I said, I'm assuming you're familiar with HTML and have seen forms in action. If you know the HTML codes for generating forms, you know that the <FORM> tag requires two arguments: METHOD and ACTION. The ACTION is the URL representing the script which is to receive the form information. The METHOD (right now either GET or POST) represents the way in which the information will get passed to the script. GET is slightly more limited (mostly in maximum length of information it can pass), but is slightly easier to deal with. If you have any substantial text entry fields (esp. TEXTAREAs), you'll want to use POST. SO, what's the difference? Here's how information is passed using METHOD="GET":
  1. FORM elements' (INPUTs, TEXTAREAs, SELECTs, etc.) names are paired with their contents.
  2. All such name/value pairs are joined together with an &.
  3. The entire string is URL encoded.
  4. This string is then passed to the ACTION script in the environment variable QUERY_STRING.
With METHOD="POST", it's much the same except for number 4. For a POST, the encoded string is passed to the script's STDIN, and the length of the string in bytes is passed in the environment variable CONTENT_LENGTH.

Great. So how do we use this?

METHOD="GET"

Let's start with a script to handle the information from a GET since it's slightly easier:
#!/usr/local/bin/perl                                   #1
@name_value_pairs=split('&',$ENV{'QUERY_STRING'});
foreach $name_value_pair (@name_value_pairs)
  {
   ($name,$value)=split('=',$name_value_pair);          #5
   $value=~s/+/ /g;
   $value=~s/%([0-9A-Fa-f][0-9A-Fa-f])/hex($1)/g;
   $form{$name}=$value;
  }
print "My name is $form{'name'}\n";                     #10
print "I live at $form{'address'}\n";
print "My ZIP code is $form{'zip'}\n";

So, again, we have some new stuff to figure out:
split
This breaks a string into an array, seperating elements at the specified character. So in line 2, we're breaking up the full string ("name1=value1&name2=value2...") into an array ("name1=value1","name2=value2",...).
s/+/ /g;
This is how we URL decode the string. The s/// operator simply replaces whatever is in the first set of /'s with whatever's in the second set. Line 6 says change all the +'s into spaces. The g means do it globally -- on all occurrences of + there are in $value.
=~
This modifies a string based on the operation after it. Just as $counter++ really means $counter=$counter+1, =~s/+/ / is a short hand way of saying something like "$value=$value except the plusses are spaces".
Line 5 breaks up each element of the "name=value" array, and line 8 creates an associative array out of them. By the time the program gets to the print statements, %form would look like ("name","Jane Doe","address","35 W. 4th St.","zip","10003"). We made an associative array where we can say the name of the form element and we'll get back what the user put in that spot in the form.

Now you can see why Perl and associative arrays are so useful for Webstuff.


METHOD="POST"

#!/usr/local/bin/perl
###### The next line is the important one:
read(STDIN,$buffer,$ENV{'CONTENT_LENGTH'};

@name_value_pairs=split('&',$buffer);
foreach $name_value_pair (@name_value_pairs)
  {
   ($name,$value)=split('=',$name_value_pair);         #5
   $value=~s/+/ /g;
   $value=~s/%([0-9A-Fa-f][0-9A-Fa-f])/hex($1)/g;
   $form{$name}=$value;
  }
print "My name is $form{'name'}\n";                    #10
print "I live at $form{'address'}\n";
print "My ZIP code is $form{'zip'}\n";

As you can see, the only difference is how we get the encoded form information. With a POST, we need to read from the STDIN for $ENV{'CONTENT_LENGTH'} bytes. In this case, we created a variable called $buffer to hold the information that $ENV{'QUERY_STRING'} held in the GET example. The major advantage of a POST is that you aren't limited by the 256 character limit imposed by the Unix command line.
So now you know how to take in user input. What you do with it is where the creativity of programming and design comes in. There is still one important piece remaining: How to send information back out to the user.

Wait, let me take a take a step back and catch my breath.