Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

CGI parameters as global variables

by icius (Sexton)
on Jun 19, 2002 at 19:18 UTC ( [id://175811]=perlquestion: print w/replies, xml ) Need Help??

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

I am trying to take all of the QUERY_STRING parameters and place then in global variables using the parameter name as the variable name. I think I have started down the right track with:
my %Params; if($Query->param) { %Params = $Query->Vars; }
My next thought is to iterate through the Params hash and use $$ to assign to variables like so:
while (my ($key, $value) = each %Params) { my $$key = $value; }
Of course being a good boy and using strict this poses a problem as the new variables are not accessable outside of the while loop. I have been convinced of the evils of "::" from previous posts. So, anyone have any ideas?

Replies are listed 'Best First'.
(jeffa) Re: CGI parameters as global variables
by jeffa (Bishop) on Jun 19, 2002 at 19:35 UTC
    Are you using CGI.pm? It allows you to get parameters as a hash reference if you really, really want to:
    # from the docs use CGI ':cgi-lib'; my $params = Vars;
    But i personally prefer the param() method, as you don't have to worry about hash name collisions.

    Anyway, your while loop seems very unecessary. each returns a key-value pair - the value is already set in the ... value. You can always get that value with $Param{$key}. Why import into a package?

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
Moving CGI parameters to a hash
by jarich (Curate) on Jun 20, 2002 at 02:18 UTC
    Let's pretend that you have a very good reason for wanting to create a hash of all of your CGI parameters. Perhaps such a reason might be that you want to assign defaults for fields that might come in empty.

    As discussed above making all of these values global is bad (they'll pollute your namespace and mean that I can send in whatever variables I like and perhaps mess up your script) and using a hash in a regular expression as you had planned to is easy enough.

    So you might do this this way:

    use CGI; use strict; my $query = CGI->new(); # set up my defaults my %parameters = (name => ["Anonymous"], address => ["No fixed abode"], phone => ["Not Available"]); # pull everything out of param and put in # my hash. foreach my $key ($query->param()) { $parameters{$key} = [$query->param($key)]; }
    This will give you a hash of array references with all your values in them. We have to use array references because you might have a checkbox group or select list returning multiple values.

    Note that if you're providing defaults, now is a good time to ensure you only get the parameters that you want, not all the ones that the user has given you. So change the foreach line to be:

    foreach my $key (keys %defaults)

    Now, you wanted to be able to substitute these values into an SQL statement. Let's pretend that you've already made them untainted. Please untaint them. This substitution can be done like this:

    # then to do your substitution: $SQLStatement =~ s/\$(\w+)/$parameters{$1}[0]/eg;
    BUT be aware that this ONLY takes the first of all the multiple answers returned. This might come back and bite you some time. It would have happened even if you had turned all the parameters into globals though.

    A solution, depending on your table design and lots of other things might be to do the following:

    foreach my $key (keys %defaults) { foreach my $value (@$key) { $SQLStatement =~ s/\$(\w+)/$value/eg; # then use your $SQLStatement .... } }
    But that really does depend on what $SQLStatement looks like etcetera.

    Hope this helps.

    jarich

Re: CGI parameters as global variables
by boo_radley (Parson) on Jun 19, 2002 at 19:37 UTC
    look in CGI for 'IMPORTING ALL PARAMETERS INTO A NAMESPACE'. Note that doing this in main is evil. Additionally, "::" is not evil by most lines of thought.
Re: CGI parameters as global variables
by Aristotle (Chancellor) on Jun 19, 2002 at 20:26 UTC
    Doing so is a bad idea. The least you must do is check the names of the parameters you have been passed. Otherwise, everyone will be able to change the values of variables within your script at will; even those you did not intend for public consumption. Say you have a $filename in your script and someone passes filename=/etc/passwd to your script.. depending on your script's innards, a lot of malady might happen. CGI scripts are a very hostile environment and you should never trust any of your input data. I urge you to read Ovid's excellent CGI course to learn a sense for the potential problems.

    Makeshifts last the longest.

Re: CGI parameters as global variables
by shotgunefx (Parson) on Jun 19, 2002 at 19:28 UTC
    If you are using CGI.pm there is a method (don't remember the name, look at the docs) that let's you import it into a specific package outside of main (to avoid collisions), not that this is neccassarily the best way to go (globals I mean)

    -Lee

    "To be civilized is to deny one's nature."
Re: CGI parameters as global variables
by George_Sherston (Vicar) on Jun 19, 2002 at 19:43 UTC
    You've probably thought this through, but just in case, is this really what you want to do? What can do by doing this that you couldn't do with a ref to %ENV? - which can be passed around and operated on at low cost.

    § George Sherston
Re: CGI parameters as global variables
by icius (Sexton) on Jun 19, 2002 at 20:25 UTC
    Thank you for the quick replies. I think I confused things by using QUERY_STRING in my description. I am using CGI.pm and not %ENV to get the parameters. The reason I need these things in global variables at all is that I am using the following regexp later on:
    $SQLStatement =~ s/(\$\w+)/$1/eeg;
    That particular statement won't evalute hashes or I would just access the Params hash directly. Jeffa, I hope that answers your question as to why. boo_radley and shotgunefx, I think you hit the nail on the head. I am going to try bringing it into a namespace that way. Thank you.
      Substituting with values from a hash is possible:
      my %data = ( foo => 'oof', bar => 'rab', ); my $text = "foo/bar"; $text =~ s/(\w+)/$data{$1}/g; print "($text)\n";

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://175811]
Approved by shotgunefx
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (4)
As of 2024-04-25 06:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found