in reply to Creating vars from URI and printing %ENV

The usage of symbolic references isn't the cleanest way to implement variables named with respect to the passed parameter and in all likelihood will create many problems under strict usage. Indeed, the use of symbolic references has been discussed previously here and here.

Additionally, multiple parameters with the same name are permissable with CGI queries, but excluded by your code (by the unless $$key conditional).

An alternate method to perform something similar would be to use the code below that will result in passed values being stored in a hash indexed by the parameter name:

my $cgi = CGI->new; my %param = map { $_ => $cgi->param($_) } $cgi->param();

This code allows you to perform similar variable assignment without the use of symbolic references.

Also, strongly consider use strict and -w.

 

Update : The advice of crazyinsomniac below with regard to $cgi->Vars is by far the better option to the map code above.

 

perl -e 's&&rob@cowsnet.com.au&&&split/[@.]/&&s&.com.&_&&&print'

Replies are listed 'Best First'.
(crazyinsomniac) Re^2: Creating vars from URI and printing %ENV
by crazyinsomniac (Prior) on Dec 28, 2001 at 16:32 UTC
    Time and time again I see:
    my $cgi = CGI->new; my %param = map { $_ => $cgi->param($_) } $cgi->param();
    and time and time again I have to say:
    use CGI 2.79; my $cgi = CGI->new; my %param = $cgi->Vars;
    If you want the symlinks still, there is always CGI::Lite
    %form = ('name' => 'shishir gundavaram', 'sport' => 'track and field', 'events' => '100m'); $cgi->create_variables (\%hash); #now you have: $name, $sport and $events. Convenient, huh?

     
    ___crazyinsomniac_______________________________________
    Disclaimer: Don't blame. It came from inside the void

    perl -e "$q=$_;map({chr unpack qq;H*;,$_}split(q;;,q*H*));print;$q/$q;"

      Yes, the map is broken, but only because there is no taking into account multiple values for a name. If that is fixed, I prefer it to Vars() for two reasons. First, you can use a proper data structure instead of having to split on NULs. Second, why introduce NULs when we know that they can be used to create security holes? One way to fix the map is this:

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

      That works, but then all values are array refs and many object. A cleaner method allows most values to simply be values and only create array refs when you have multiple values:

      #!/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]; }

      Of course, some might argue about inconsistent mixing of array refs and regular scalars, but I still think it's cleaner.

      Cheers,
      Ovid

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

        Of course, some might argue about inconsistent mixing of array refs and regular scalars, but I still think it's cleaner.

        I'll bite. If you (obviously not Ovid, who knows better) don't know whether your form field can generate multiple values, you don't understand the problem space. There be dragons.

        Besides that, what if someone malicious or curious decides to edit the HTML locally or to submit extra information? If you don't check *every* variable to see if it's an array reference, the best you can hope for is a harmless crash. Try that with CGI, which for all its warts, handles this nicely.

        Yeah, the map solution with array references is a sight better than the old cgi-lib.pl approach, but it's merely false laziness. You have to know what data to expect.