http://www.perlmonks.org?node_id=98772

relayeddeaction has asked for the wisdom of the Perl Monks concerning the following question:

Very new to Perl here..so excuse my lack of understanding on this fundamental. Been screwing around with Perl on my computer for a few weeks.. finally decided to see if I could get a CGI script to manipulate data from a form. Can get the data from the query string (the form method is just GET, so I wasn't bothering to check if it's POST or GET...). Here's the code:
print("Content-Type: text/html\n\n"); print("<HTML><BODY>"); $QSTRING = $ENV{'QUERY_STRING'}; $QSTRING =~ s/\+/ /g; print("<P align=center><B>(\$)QSTRING</B>: $QSTRING</P>"); # Split the $QSTRING by the ampersand and assign the parts to @QSTRING @QSTRING = split(/&/,$QSTRING); # Check the values in @QSTRING print("<P align=center><B>(@)QSTRING</B>:"); foreach $QSPart(@QSTRING) { print("&nbsp;$QSPart"); } print("</P>"); foreach $Part(@QSTRING) { %FormData = split(/=/, $Part); } # Attempt to print out the names and values of the QSTRING.... @InputNames = keys(%FormData); foreach $InputName(@InputNames) { print("<P align=center><B>$InputName</B>: $FormData{$InputName}</P +>"); } print("</BODY></HTML>");
Not sure why, but only the last name/value pair are placed in the hash. for example, the form had 3 inputs. name, age, and word (for testing purposes..heh). upon submitting the form to the script with the values .cgi?Name=my+name&Age=12&Word=xyzzy ...checking the values in the scalar & the array, things come out fine. when checking the values in the hash, i only get... Word: xyzzy ...which would be the last things in the query string. Why this comes out this way I do not know. Maybe some else does? Like I said... Only been workign with Perl for a few weeks, and please excuse how verbose this is.

Replies are listed 'Best First'.
Re: A Beginner Apparently Sucks With Hashes...
by CheeseLord (Deacon) on Jul 22, 2001 at 10:28 UTC

    I can tell you why it happens... this line right here:

    %FormData = split(/=/, $Part);

    Inside that foreach loop, you're overwriting the hash each time. You'll probably want to do something like this:

    my ($name, $value) = split /=/, $Part; $FormData{$name} = $value;

    However... there are MUCH easier ways to do parameter grabbing, and I (along with 99% of the monastery) suggest you check out and use CGI.pm, along with strict and -w, if you aren't already. Hope that helps!

    Update: Added example code.

    His Royal Cheeziness

      Following CheeseLord's advice might lead to something like:

      #!/usr/bin/perl -w use strict; use diagnostics; use CGI qw/:standard Vars/; use CGI::Carp 'fatalsToBrowser'; my @page; my %form_data = Vars; foreach my $input_name (keys %form_data) { push @page, p( {-align => 'center'}, b($input_name), ": $form_data{$input_name}" ); } print header, html(@page);

      HTH,
      Charles K. Clarkson
Re: A Beginner Apparently Sucks With Hashes...
by tachyon (Chancellor) on Jul 22, 2001 at 11:26 UTC

    Hi your question has been answered but you are doing it the hard (and also insecure and unreliable) way by parsing the CGI input yourself. Whilst it is good to know how the CGI.pm library is the gold standard and comes highly recommended.

    Here are a few links you may find useful. I answered a question like this today at Charecters problems - it shows you how to use CGI.pm to get your data as a hash and also how to output HTML with ease by using a herepage. For a run down on CGI.pm check out Use CGI or die; and No excuses about not using CGI.pm. You may also find good value in CGI Help Guide. To get to a really good CGI tutorial go to Ovid's home node and follow the link. This is the best online CGI tute - even if it is incomplete as yet. Small technical note - unlike C you dont need the parenths for print. print "Hello World!\n" is OK. Finally the New Monks node has lots of useful links to all sorts of perl stuff.

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Re: A Beginner Apparently Sucks With Hashes...
by dragonchild (Archbishop) on Jul 23, 2001 at 17:40 UTC
    This isn't a direct answer to your question, but a general Perl suggestion - check out use strict. There are hundreds of nodes about it, and several of the Perl books devote chapters to this most wonderful Perl construct. It will save you more headaches than you think could exist, especially if you plan on doing a lot of CGI work.