Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW

Best way to parse CGI params

by hakkr (Chaplain)
on Feb 15, 2002 at 11:09 UTC ( [id://145661] : perlquestion . print w/replies, xml ) Need Help??

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

Acolyte- one by one into separate vars
$email=$q->param(email); $name=$q->param(name);
Monk - all at once into hash ref
my $sr; foreach my $str qw(email name) { $sr->{$str}=$q->param($str); }
Friar- don't have to enter param names
my @names=$q->param; foreach my $str (@names) { $sr->{$str} =$q->param($str); }
The friar code above does not work for multivalued params. so I have to do @multivalues=$q->param('selectboxvalues') whenever I use mulitple select boxes or checkboxes. I'm thinking of refining this further using a ref test to handle multiple values.
my @names=$q->param; foreach my $str (@names) { if (ref($str) eq "ARRAY") { my @multi=$q->param($str); sr->{$str} =\@multi; }else { $sr->{$str} =$q->param($str);} } }
What does the saint code for this look like ?

Replies are listed 'Best First'.
Re: Best way to parse CGI params
by Caillte (Friar) on Feb 15, 2002 at 11:15 UTC

    Friar II - Son of Friar

    Why iterate?

    my %vars = $cgi->Vars();

    This page is intentionally left justified.

      You know, that strangely looks like the saint way of doing things :-)

      Although, if you really want to talk uber-demi-God way of doing things, look into the source of and look at the way Lincoln D. Stein has implemented the backward-compatible (with Steve Brenner's method of Vars with surprisingly little code ...

      sub Vars { my $q = shift; my %in; tie(%in,CGI,$q); return %in if wantarray; return \%in; }


      perl -e 's&&[@.]/&&s&.com.&_&&&print'

(Ovid) Re: Best way to parse CGI params
by Ovid (Cardinal) on Feb 15, 2002 at 16:07 UTC

    A note regarding CGI::Vars(): I never use it. It was created to ease the transition from the Perl4 and the Perl5 As a result, it uses the NUL byte (ASCII zero) to delimit multiple values. Since the NUL byte hack is so dangerous, I prefer not not to deliberately introduce them.

    One quick and easy way of getting all params is the following:

    my %param = map { $_ => [$cgi->param($_)] } $cgi->param;

    Some might prefer the following:

    #!/usr/bin/perl -wT use strict; use CGI qw/:standard/; my %params = map { $_ => get_data( $_ ) } param; sub get_data { my $name = shift; my @values = param( $name ); return @values > 1 ? \@values : $values[0]; }

    With the last snippet, if you only have one param value, the hash value is a scalar value. If you have multiple param values, the hash value is a reference to an anonymous array.

    I used to think the last method was better, but as tilly alluded to above, and as I have seen before, most code that uses the ref function has problems. Most of the time, such code can be rethought to more naturally model the problem without having to insert a lot of extra logic to see what type of reference you are getting at any given time. Of course, that comes with the caveat that the only hard and fast rule is that there are no hard and fast rules.


    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

      Actually you have just inspired my new one-line drop-in replacement for $cgi->Vars()...
      $params = $cgi->Vars();
      ... becomes ...
      $params = { map { $_ => ($cgi->param($_))[0] } $cgi->param };
      ... or if you want a straight hash instead of the hashref that Vars() gives you, you can ...
      %params = map { $_ => ($cgi->param($_))[0] } $cgi->param;
      This way seems DWIMmer since it returns what I expect most people *think* $cgi->Vars() does, which is a hash with a single scalar as the value, which ignores multiple instances of cgi params. I can't think of any time where I've actually needed multiple instances of the same name CGI parameter back (Then again, I avoid multi-select boxes ;). If I do need multiple values, you can still get at them via $cgi->param('foo'), or Ovid's method. Since mine doesn't require dereferencing the arrayref, it may be a little more convenient for newbies.

      -- KILNA - pop music for cyborgs -
Re (tilly) 1: Best way to parse CGI params
by tilly (Archbishop) on Feb 15, 2002 at 14:23 UTC
    The saint suits his solution to the situation, but uses, and with just a small number of arguments prefers individual variables so he gets his beloved typo check. With many, well he tries to avoid that. :-)

    The saint also does not like data structures that automatically convert between being regular strings and anonymous arrays. Code like that just forces you to later check for the data type and code stuff twice.

Re: Best way to parse CGI params
by shotgunefx (Parson) on Feb 15, 2002 at 17:04 UTC
    Not a saint but what about...


    "To be civilized is to deny one's nature."
Re: Best way to parse CGI params
by Parham (Friar) on Feb 15, 2002 at 13:06 UTC
    FOR FUN i started making my own lil' SIMPLE parser. I think it works pretty well and takes care of most problems.. check it out at my scratchpad here :D