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

Dear monks, I'd like to ask for help understanding this problem.

The context is a mod_perl Apache http server and DBI access to mysql.

The action of an html form is a perl handler. The handler starts off by getting the request object and reading an identifying cookie:

sub handler { my $r = Apache2::Request->new(shift); my %in_cookies = Apache2::Cookie->fetch ($r); my $session = $in_cookies{"ID"} && $in_cookies{"ID"}->value; ...
The handler takes arguments from $r->param and writes them to a mysql table by means of a database handle obtained from DBI->connect.

The problem: it has occurred at least once that data from one call to the handler has persisted to the next and has been written to a record belonging to a different session. Specifically, this section of code misfired, the hash %ship_address somehow retaining data from its previous assignment:

while ( my ($key,$value) = each %ship_address ) { $dbh->do("update bill set ship$key = ? where session = ?", undef, $ +value, $session);
The 2nd customer was very surprised to learn he lived on the 5th floor of a one story house...

I am uncertain how to isolate the problem. Can you help? Thanks.

Replies are listed 'Best First'.
Re: keeping variables separate
by almut (Canon) on Apr 20, 2009 at 16:08 UTC
      Thank you and kennethk for responding. Maybe I don't understand the libapreq2 module. But it looked simple enough.
      sub handler { # use Apache2::Request; is in startup.pl my $r = Apache2::Request->new(shift); my $shipaddr2 = $r->param("shipaddr2"); ...
      I don't understand how it would be possible for a "new" $r to retain a parameter from an old $r, even if, as kennethk suggests the parameter in the new $r has not been explicitly overwritten.

        I think it's not so much the $r object and its params, but rather some other data structure that's retaining the values.  At least, in your original post, it isn't clear where %ship_address comes from, how data gets into it, if it's global (which could be the problem), or if you do empty it on every request, etc.  In other words, it's hard to provide anything else than general hints without seeing the actual (complete) code...

Re: keeping variables separate
by kennethk (Abbot) on Apr 20, 2009 at 15:38 UTC
    In this scenario, we really need to see the code that stores your values in %ship_address. My guess is that there are keys which used for some subset of all cases (like perhaps floor) and your set statements are going through the new keys, leaving any unused keys with their original value. This can be simply resolved by explicitly initializing %ship_address to an empty list. So

    my %ship_address; foreach (@customers) { while (@list) { my $key = shift @list; my $value = shift @list; $ship_address{$key} = $value } # And process... }

    should be

    my %ship_address; foreach (@customers) { %ship_address = (); while (@list) { my $key = shift @list; my $value = shift @list; $ship_address{$key} = $value } # And process... }