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

Hello all...

I'm working on a kind of Rube Goldberg-ish series of CGI scripts, each of which needs to create web pages which in turn pass variables along to other scripts via A HREF="..." fields. (In other words, I'm passing hidden state parameters in links.)

Question: is there a good way of building up a query string with escaped names and values? I'm finding myself having to write routines such as:

my $query_str = join('&', map("@{[CGI->escape($_)]}=@{[CGI->escape(par +am($_))]}", qw(foo bar baz)); print "http://www.foo.com/cgi-bin/foo.pl?$query_str";
But this gets old fairly quickly. I'd prefer to do something like this:
my $uri_query = URI::Query->new('http://www.foo.com/cgi-bin/foo.pl'); foreach ( qw( foo bar baz ) ) { $uri_query->set_param($_, param($_)); } print $uri_query->as_string();
The regular URI object will let me set the query string-- but won't let me do parameter-by-parameter stuff. The CGI module will let me use the object-oriented interface to create and alter a blank query-- but seems to use semicolons as delimiters, which has caused problems in "Refresh" headers. (When standards collide!)

I could either continue writing custom routines all the time, or I could write a simple module to handle building the query. My question is: is there anything out there already that handles this? It's such a common thing to do that there must be an easy solution that I'm missing.

Much appreciation...

stephen

Replies are listed 'Best First'.
RE: Best way of doing CGI passthroughs
by arturo (Vicar) on Nov 08, 2000 at 00:44 UTC

    May I commend unto you the URI::Escape module.

    Update d'oh! posted too soon. Of course you can do w/o that module, just use CGI's version of that method. But the principle is the same

    I'd do something like this: assuming you have all the name/value pairs stored in a hash with names as keys and values as values(duh =)

    my $query_string; foreach (keys %nvpairs) { # guess which module defines uri_escape =) $query_string .= "&" if $query_string; $query_string .= "$_=". uri_escape($nvpairs{$_}); } # assuming $q is a CGI query object ... print $q->a({href=>"http://www.foo.com?$query_string"}, "click me!");

    Philosophy can be made out of anything. Or less -- Jerry A. Fodor

Re: Best way of doing CGI passthroughs
by chromatic (Archbishop) on Nov 08, 2000 at 01:18 UTC
    If you're not tied to the idea of the GET method (that is, creating a link with a query string), you might look to using POST (form submission).
    <form method="POST" action="second_script.cgi"> <input type="hidden" name="username" value="whatever"> <input type="hidden" name="show_size" value="some ridiculous number li +ke 8 3/4"> <input type="hidden" name="belabor the point?" value="Yes & it's fun!" +> <input type="submit"> </form>
    The best part about that is that you can use a heredoc or interpolate variables into the value sections. The browser or user agent will be the one to handle escaping the parameters correctly.

    Using CGI, there's no need to wonder if users use GET or POST to send data. Your interface is the same.

      Yes, unfortunately, I am constrained to using GET parameters for reasons too ticklish to tell. (I'm passing parameters to a bit of third-party software which does a GET-request which flashes a light that causes a highly-trained parrot to... oh never mind... :)

      However, your point is well made.

      stephen

Re: Best way of doing CGI passthroughs
by Anonymous Monk on Nov 08, 2000 at 04:09 UTC
    The CGI module should use '&' to separate parameters in query strings UNLESS you're using the -newstyle_urls pragma. So you here's how to cheat if it is on and you don't want to take -newstyle_urls out of the use statement:
    my $q = CGI->new(%parameters); $CGI::USE_PARAM_SEMICOLONS = 0; print $q->query_string;
Re: Best way of doing CGI passthroughs
by cianoz (Friar) on Nov 08, 2000 at 01:30 UTC
    maybe you should use Apache::Session (or just a tied hash with MLDBM) and pass only the session id on the query string..