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

Hello

I wrote a sample code for trying CGI::Session and it works quite well but I don't understand some aspects of it, which is confusing.

All I am doing is to pass a variable from one page to another (posting to the same script) using CGI::Session. Below is the sample code..

Script

#! /usr/bin/perl -wT use strict; use lib "..."; use CGI qw/:standard :nosticky :delete_all :escapeHTML :html3 :all/; use CGI::Session; use CGI::Carp 'fatalsToBrowser'; use HTML::Template; my $q = CGI -> new(); my $session = CGI::Session->load() or die CGI::Session->errstr; if ( $session->is_expired ) { print $session->header(); print "Your session expired, inevitably!"; exit(0); } elsif ( $session->is_empty ) { $session = new CGI::Session(); } $session->save_param(); ###$session->load_param(); my $user = $session->param( "user" ); my $sid = $session->id(); my $cookie = $q->cookie( -name => $session->name(), -value => $sid, -expires => "+5" ); my $nextpage = 'test_cgi_session.pl'; $session->delete(); print $q->header( -cookie => $cookie ); my $template = HTML::Template->new( filename => 'test_cgi_session.tmpl +' ); $template->param( heading => "Test Session" ); $template->param( nextpage => $nextpage ); $template->param( user => $user ); $template->param( sessionid => $sid ); print $template->output();

Template File

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" + /> <title><tmpl_var name=heading></title> </head> <body> <script>javascript:history.forward()</script> <script> function submitform( button ) { alert ( 'button is ' + button ); document.data.button.value = button; document.data.submit(); return false; } </script> <form method="post" action="<tmpl_var name=nextpage>" enctype="applica +tion/x-www-form-urlencoded" name="data"> <input type="hidden" name="button" value="" /> <br> <br> <table border="0" align="center"> <tr><td> <input type="input" name="user" value="<tmpl_var name=user>" /> </tr></td> <tr><td> <input type="input" name="sessionid" value="<tmpl_var name=sessionid>" + size="100" /> </tr></td> <tr align="center"> <td><input type="submit" name="submit" value="submit" onclick="return +submitform('submit')" /></td> </tr> </table> <br> <br> </form> </body> </html>

On loading the script, the username textbox is 'blank' and the sessionid textbox has the id that is generated. Once I enter a value in the username textbox and submit, the same name appears in the next screen and a new session id is displayed as well. Everything looks good but my doubts are:-

1) I understand the reason for the generation of new id everytime because I have included '$session->delete()' at the end of the script (if I comment ' $session->delete();' , and execute the script, the session id doesn't change. I presume it would change if I execute the script after 5 minutes as I had set the 'expire' option as '5' )

2) I am confused as to how the username is picked up correctly, if I use'$session->delete();' in the script? (I don't see the 'cgisess_............' in the /tmp folder and I am sure it is getting deleted )

3) Also, I am not sure why I don't need '$session->load_param(); ' call?

I am really not sure if I am using CGI::Session correctly, although I am getting the desired results. (The idea is to use CGI::Session instead of passing variables from one page to another as 'hidden variables' )Please help.

Update:

I updated with the '-nosticky' pragma but it still behaves the same way it did earlier. Hence, I tend to think that it is something else other than 'sticky' or 'nosticky' option. Any thoughts?

Replies are listed 'Best First'.
Re: Confusion using CGI Session
by shmem (Chancellor) on Dec 07, 2006 at 00:26 UTC
    Have a look (again ;-) at the CGI documentation.
    -nosticky

    By default the CGI module implements a state-preserving behavior called "sticky" fields. The way this works is that if you are regenerating a form, the methods that generate the form field values will interrogate param() to see if similarly-named parameters are present in the query string. If they find a like-named parameter, they will use it to set their default values.

    Sometimes this isn't what you want. The -nosticky pragma prevents this behavior. You can also selectively change the sticky behavior in each element that you generate.

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

      Thanks. Have I used CGI::Session correctly? Do I have to use $session->load_param(); to retrieve the variables?

      Update:

      I updated with the '-nosticky' pragma but it still behaves the same way it did earlier. Hence, I tend to think that it is something else other than 'sticky' or 'nosticky' option. Any thoughts?

        Sorry for my completely bogus first reply *blush*

        While it sounds good, it doesn't point you into the right direction.

        CGI::Session encapsulates CGI to store parameters, cookies and so on in a serialized data structure, so you don't need to use both of them. Choose one, use one.

        Maybe you mended your confusion in the meantime - anyways:

        2) I am confused as to how the username is picked up correctly, if I use'$session->delete();' in the script? (I don't see the 'cgisess_............' in the /tmp folder and I am sure it is getting deleted )

        You grab the params before the call to $session->delete()

        my $user = $session->param( "user" ); my $sid = $session->id(); my $cookie = $q->cookie( -name => $session->name(), -value => $sid, -expires => "+5" ); my $nextpage = 'test_cgi_session.pl'; $session->delete();

        pass them to your template

        $template->param( user => $user ); $template->param( sessionid => $sid );

        and have them stuck into the value attribute of your inputs

        <input type="input" name="user" value="<tmpl_var name=user>" /> </tr></td> <tr><td> <input type="input" name="sessionid" value="<tmpl_var name=sessionid>" + size="100" />

        so it would be rather odd for $user not to show up in the text field.

        3) Also, I am not sure why I don't need '$session->load_param(); ' call?

        You need the $session->load_param() call if the only value passed into your cgi is the session ID, and you want to restore the params from the previously stored serialized data structure, i.e. if there wasn't any user name passed in, and you want the username to be passed to subsequent pages nonetheless - just the opposite of what you expected your script to do ;-)

        I am really not sure if I am using CGI::Session correctly

        Those who are sure, aren't ;-)

        Look for the method 'dump' in CGI::Session and include dump($session) in your output to see what's in that session thing.

        --shmem

        _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                      /\_¯/(q    /
        ----------------------------  \__(m.====·.(_("always off the crowd"))."·
        ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}