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

this may be a little bit long, but im trying to demonstrate something that i can't figure why it's happening - when you try to load a session before a sub that also loads the session, it won't be able to store it for next page load! Why?

to demonstrate :
test1.pl will generate a session id and move to test2.pl
test2.pl will initially try to display any messages that were added. On first load, you should see it says no messages are found.
When you click on "refresh page", you will see "TESTING 1 2 3 SHOULD SHOW".
If you comment off MARKING 1 to 3 and try to start from test1.pl to test2.pl again, once "refresh page" is clicked, no messages are shown!

library.pl is the file that is imported from test2.pl


test1.pl :
#!/usr/bin/perl use strict; use warnings; use CGI; use CGI::Carp qw/fatalsToBrowser/; use CGI::Session qw/-ip-match/; require "library.pl"; # instantiate a new CGI object my $cgi = new CGI; my $sessionid; my $session = new CGI::Session(); my $sessionid = $session->id(); print<<OUTPUT; <html> <body> <br><br> <form action="test2.pl" METHOD="POST"> <input type="hidden" name="sessionid" value="$sessionid"> <input type="submit" value="Generate Session"> </form> </body> </html> OUTPUT print xxx;
test2.pl
#!/usr/bin/perl use strict; use warnings; use CGI; use CGI::Carp qw/fatalsToBrowser/; use CGI::Session qw/-ip-match/; require "library.pl"; # instantiate a new CGI object my $cgi = new CGI; my $sessionid = $cgi->param("sessionid"); my $msg = $cgi->param("message"); print<<OUTPUT; <html> <body> OUTPUT #display any added messages if any &DisplayMessage; # PERCULIAR - remove these and you won't see the "TESTING 1 2 3 SH +OULD SHOW" anymore! how to retain? # MARKING 1 # my $session = CGI::Session->load($sessionid); # MARKING 2 # $session->param("otherThings", "......."); # MARKING 3 #TO TEST .. THIS IS WHERE MESSAGE IS ADDED &AddMessage("TESTING 1 2 3 SHOULD SHOW\n\n"); print<<OUTPUT; <br><br> <form action="test2.pl" METHOD="POST"> <input type="hidden" name="sessionid" value="$sessionid"> <input type="submit" value="Refresh Page"> </form> </body> </html> OUTPUT print xxx;
library.pl :
#!/usr/bin/perl use strict; use warnings; use CGI; use CGI::Carp qw/fatalsToBrowser/; use CGI::Session qw/-ip-match/; # instantiate a new CGI object my $cgi = new CGI; my $sessionid = $cgi->param("sessionid"); sub AddMessage { my ($text)=@_; #open up existing session and add message my $session = CGI::Session->load($sessionid); $session->param("message", $text); print "added a new message.\n"; } sub DisplayMessage{ #prints the message out from previous saved session my $session = CGI::Session->load($sessionid); if($session->param("message")){ print $session->param("message"); }else{ print "no messages found.\n"; } } return 1;

Replies are listed 'Best First'.
Re: need serious help with CGI::Session
by almut (Canon) on Sep 26, 2007 at 10:07 UTC

    Your problem most likely is that you're using several CGI::Session objects in one run of the program. Every time you do

    my $session = CGI::Session->load($sessionid);

    a new session object (but not a new session/ID) is created, which will autoflush its data when it goes out of scope. If you maintain several CGI::Session objects (and thus separate in-memory representations of the session data) in one run of the program, the one that goes out of scope last will "win", as it overwrites (on-disk) any changes that may have been flushed before...

    Your $session object that you created in between the "MARKING" comments is file-scope and will thus not go out of scope before the CGI terminates. The other one created within AddMessage() will go out of scope at the end of the subroutine. In other words, the file-scoped one wins, as it writes to disk later.

    Try putting an explicit $session->flush() after "MARKING 3", or put an extra { ... } block around the "MARKING" section, and you should see different behaviour, i.e. in this case, the stuff added in AddMessage() will be flushed later.

Re: need serious help with CGI::Session
by adrive (Scribe) on Sep 27, 2007 at 01:28 UTC
    almut, thanks alot! you helped me solve the mystery that's been plaguing me for weeks!!
Re: need serious help with CGI::Session
by Anonymous Monk on Dec 24, 2008 at 07:01 UTC
    I need to maintain same CGI sessionId in two different servers. If not my user gets logged out every time if the sessionid doesn't match with my sessionid saved in DB when created the sessioId for the first time for a particular user