PDA

View Full Version : cgi-lib.pl (is there a better way?)


Tony Davis
11-03-2005, 04:09 PM
I have always used cgi-lib.pl to parse form data. It has always done the job OK, but now I have a form that has MANY fields, and I wonder if there is a better way. I would like to save the field name AND form value in a file. I am currently saving only the field value, so I have to remember what everything is. Can anyone give me some advice on how to handle this better?

Here is an example of what I currently do:

require 'cgi-lib.pl';
&ReadParse(*input);
$next_page = $input{'next_page'};
$current_page = $input{'current_page'};

Thanks!
-tdavis

FishMonger
11-03-2005, 04:39 PM
Yes there is a much better method, use the CGI module.

http://search.cpan.org/~lds/CGI.pm-3.11/CGI.pm

Tony Davis
11-03-2005, 05:48 PM
if ($ENV{'REQUEST_METHOD'} eq 'POST') {
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/, $buffer);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex $1))/eg;
$FORM{$name} = $value;
}
}

This seems to give me what I want if I want to save the string as a whole to a file. I am not sure yet about reading and then parsing in order to display the data on another page.

-tdavis

FishMonger
11-03-2005, 06:53 PM
NO, you DON'T want to do it that way. That method has been outdated for over 10 years. Experienced Perl progrmmers shutter when they see someone using that method.
Use the CGI module, it parses both POST and GET requests with the same line in your script:#!/usr/bin/perl -w

use strict;
use CGI;

my $q = new CGI; # parse/decode (get or post) querry string
my %FORM = $q->Vars; # put into a hash
If you want to put the form fields into seperate variables, you can do this:
#!/usr/bin/perl -w

use strict;
use CGI qw(:standard);

my $firstname = param('firstname');
my $lastname = param('lastname');
The module's documentation gives numerous examples and explainations on parsing forms and creating pages.

Tony Davis
11-04-2005, 04:17 PM
OK. Thanks! I will give that a try.

Can I ask one more thing about forms?

I tried using a TABINDEX thinking I could sequence the fields the way I want to in my script (there are so many that hard-coding is just too hard), but that does not seem to work. The field names are not really descriptive enough, so I put alternatives in a table and use those, but they are not in the right corresponding sequence.

Is this possible, or am I stuck with those fields names I made up in the form?

Thanks again!
-tdavis

FishMonger
11-04-2005, 04:47 PM
Are you talking about the order in which the user navigates ("tabs") through the form, or when your script is parsing the form? When parsing, the TABINDEX doesn't matter.

You can retrieve the fields in any order you wish and as many or as few as you wish or retrieve them all at once with:
my %FORM = $q->Vars;

Tony Davis
11-04-2005, 05:01 PM
Yes, tabindex is not what I need.
I need them in a specific order when I parse them out.

FishMonger
11-04-2005, 05:18 PM
I need them in a specific order when I parse them out.Rarely is there a need to retrieve them in a specific order, but there's no reason why you can't.

Can you post the portion of your script that is parsing the form and the desired order that you want the fields?

Tony Davis
11-04-2005, 06:48 PM
The parsing code I am currently using is above. I will try and change that per your advice. I want to redisplay the fields in a summary page, which works fine, but some of the field names are a little abbreviated. So, I have a table that contains better descriptions. But, the problem with that is, they have to line up. I dont see any pattern to the order; eg., left to right, top to bottom?
I may have to change the field names and use them. I guess that is the most common method?

FishMonger
11-04-2005, 07:58 PM
The easiest and best approach, IMO, is to change the names of the form fields appropriately and then retrieve and put them into a hash 1 step. The other option would be to retrieve each field separately, assigning a scalar to each one.

my %form_fields = $q->Vars;

or

# these can be retieved in any order you wish
my $Fname = param('firstname');
my $Lname = param('lastname');
etc
etc

In either case, you'd output them in any order you wish, the only thing that changes is syntax based on the type of variable you're using.

print "$Lname, $Fname";

or

print "$form_fields{'lastname'), $form_fields{'firstname')";