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

Hello all,

I'v posted this question on a (Perl)Beginners List because the answer is probably going to be perfectly clear, once I understand it; however, I've received no replies. Perhaps this goes beyond the "beginners" on the other list.

I've read a lot of doc's, etc. regarding passing parameters between html documents via the parameter-pairs listed in the query string of the url. Additionally, Guelich, Gundavaram and Birznieks' book, "CGI Programming" (2nd. ed., O'Reilly & Assoc., 2000), p. 94, explain how to "add" a new parameter to the query string via the url, e.g., the results of executing the following instruction:

   $q->parm( title => "Web Developer" );

will appear as "&title=Web+Developer" in the query string. This works, but the authors suggest that a parameter can be "modified" and/or "deleted", too. I have assumed that this means that the parameter value in the url's query string can be (should be) modified as in changed? I cannot change a value, or delete a parameter from the query string in the url. If for example, I have a parameter, "table", (i.e., a MySQL table that in this case, is to be dynamically selected later)that originates in pgm-A but is not assigned a value, then when the parameter is presented to pgm-B, the query string has a value of "&db_name=cookbook&table=&etc=etc". Notice that "&table=" is not associated with a value. If I execute an instruction such as:

   $q->param( table => "vendors" );

. . .the result (in additional to other parameters)is: "&db_name=cookbook&table=&etc=etc&table=vendors". Notice that the operation did not change the value of the existing "table" parameter, but "pushed" or ADDED another "table=vendors" pair onto the query string. Also, as the authors suggested, I have tried to execute:

$q->delete( "table" );

. . .but this will not delete or otherwise remove the "table" parameter from the query string. Also, I've been scanning through the source for CGI.pm, and apparently there is not a packaged subroutine for something like $q->modify( "table" );.

Suggestions?

Ron Wingfield

FreeBSD 4.8 -- Apache http 2.0.28 -- MySQL client/server 4.1.7 Perl 5.8.5 -- p5-DBD-mysql-2.9004 driver -- p5-DBI-1.46

Replies are listed 'Best First'.
Re: Modifying Parameter Values w/CGI.pm
by legato (Monk) on Jan 05, 2005 at 00:37 UTC

    Your table= parameter is undefined, so CGI.pm pretends it doesn't exist. Interestingly enough, the addition of the new value to the end of the query string will be interpreted correctly.

    So, when you pass the '&db_name=cookbook&table=&etc=etc&table=vendors' back to another CGI script, the script will percieve a parameter named 'table' with one value 'vendors'.

    As an aside, I recommend CGI::Simple, which has the same interface as CGI, but works faster and better.

    Anima Legato
    .oO all things connect through the motion of the mind

      Thanks, Legato, I hadn't thought of that. As I've mentioned, I'm new to serious Perl, CGI, etc., and I still tend to think in terms of traditional transaction-oriented, CPU/dumb-terminal architecture.) Perhaps I could try an experiment to have the parent pgm-A assign some default value, e.g., "foobar", and then see if the value will (hopefully) be changed. That will be simple enough.

      Some may ask "why not just omit the unused parameter from being included by pgm-A?" Well, obviously, why not, other than I want to use a "copy-book" include for a parameter list. In OS/400 for example, whether COBOL or RPG, I usually just include a pointer to a data structure as a single parameter, rather than a list of individual scalers (MUCH more efficient). This datastructure can be the description of an entire record format (and in the case of OS/400, an externally described data-structure); therefore, the entire record format with value content can be passed as a single parameter. If some fields in the data-structure are zero, blank, or null, . . .it doesn't matter.

      Also, thanks for the "heads-up" on CGI::simple. Ron W.

Re: Modifying Parameter Values w/CGI.pm
by injunjoel (Priest) on Jan 04, 2005 at 23:53 UTC
    Greetings all,
    Though Im not sure why you are manually altering your query string, I will leave that alone.
    Here is something I was messing around with to hopefully get your desired functionality.
    sub modify_query_str { #takes the parameter you wish to modify and the value you wish to set +it to. return $ENV{'QUERY_STRING'} unless(scalar @_ == 2); my ($key, $value) = @_; #Below is the substitution used in CGI::Util for the escape function. $value =~ s/([^a-zA-Z0-9_.-])/uc sprintf("%%%02x",ord($1))/eg; my %values = map{split /=/,$_;} split /&/, $ENV{'QUERY_STRING'}; $values{$key} = $value; return join("&", map{"$_=$values{$_}"}keys %values); }

    Simply I know but is that what you are looking for?

    -InjunJoel
    "I do not feel obliged to believe that the same God who endowed us with sense, reason and intellect has intended us to forego their use." -Galileo

      Regarding your comment, "not sure why you are manually altering your query string", . . .a fair question. In fact the authors (ibid., p.95) comment "It may seem odd that you would ever want to modify parameters yourself, . . .Setting parameters is useful for many reasons, but especially when assigning default values to fields in forms."

      Thanks for your suggestion. Looks like it will work. Still, I wonder why such a method function is not workable within CGI.pm (module). I'm new to Perl modules, etc., and I wonder if I'm just not "getting it?"

      There may even (probably) be a better approach to my immediate purpose. I've designed a module that will handle single transactions: Inquire, Update, Insert and Delete, on a MySQL database table. The module is totally generic, and will accept a parameter list consisting of $host_name, $db_name, $userid, $passwd, $table, and $pkey. To wit, I have also created a module that copies-in these "standard" parameters, and optionally contains a subroutine that will print the six hidden fields that can become parameters in the query string. My concept is analogous to using copy-books in COBOL, the #include in RPG's, or the include etc.h (file) in C. What I've discovered it that if a parent pgm-A (that does not specify a value for $table) calls child pgm-B, and this child makes the decision to specify the Vendor Master Table (in my application, the user has transversed through a host server/database login, and has made an application selection from a menu of business applications), then it is apparently difficult to insert the literal value "vndr_mstr" into the query string already containing the parameter, "&table=", i.e., (NULL), that will eventually be presented to my DBI_API.pm module.