Place inside an existing CGI that uses CGI.pm.

Pretty self-explanatory, but any argument passed on the URI field of your browser will be turned into a variable used by CGI.pm. Yes, this has several concerns, the most of which is the ability to override the default vars, so remember to always check your variables first when you get them. Using http://www.foo.com/bar=blort&baz=quux will result in $bar=blort and $baz=quux being created for you.

The second piece of that simply prints out the entire environment as passed to your webserver, inside the comment block of your HTML. WARNING: Do not leave this uncommented in production code!!! (unless you want people to see your server paths and other variables, thus making it easier to exploit). Use the second snippet for debugging purposes only!

#!/usr/bin/perl -w use Env; foreach $key ( param() ) { $$key = param($key) unless $$key; } print "<!--\n"; foreach $parameter ( sort keys %ENV ) { print "$parameter is: $ENV{$parameter}\n"; } print "-->\n";

Replies are listed 'Best First'.
Re: Creating vars from URI and printing %ENV
by davorg (Chancellor) on Dec 28, 2001 at 16:19 UTC

    Creating variables using symbolic references is a very bad idea for reasons that are discussed on this site almost every day. Creating variables using symbolic references and taking their names from user data in a CGI script creates a huge security risk on your server. Please don't use code like this on a server connected to the internet.

    Why not put the values in a hash like this:

    my %param; foreach (param) { $param{$_} = param($_); }

    or (if you have multivalued CGI parameters)

    my %param; foreach (param) { # store all parameters in arrays initially push @{$param{$_}}, param($_); } foreach (keys %param) { # promote single element arrays $param{$_} = $param{$_}->[0] if @{param{$_}} == 1; }
    --
    <http://www.dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

Re: Creating vars from URI and printing %ENV
by rob_au (Abbot) on Dec 28, 2001 at 16:03 UTC
    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'

      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.