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

Hi Monks!

My perl code here should get some parameters from my html template, but I can't figure it out why I can't get the parameters sent back from the HTML to print after a click on the button(s) on the form. I can see the parameters been passed, by the perl ignores it.
Can someone help on that? Or explain why this is happening?

The Perl code
#!/perl/bin/perl use strict; use CGI qw/:standard/; use CGI::Carp qw(fatalsToBrowser); use DBI; my $q = new CGI; print header(); #print "Test"; my $userip = $ENV{'REMOTE_ADDR'}; #print $userip; my $curr_dir; #print $userip; # Grab the current directory from $0. BEGIN { $0 =~ '(.*[\\\/])\w+\.\w+$'; $curr_dir = $1 || "./"; } my $display = &filter($q->param('display')) || ''; my $insert = &filter($q->param('insert')) || ''; my $confir = &filter($q->param('confir')) || ''; my %AoH; if($insert eq "insert"){ $AoH{MESS} = "OK your message has been received!"; }else{ $AoH{MESS} =""; } print "<br><b>I must to print these values here once the buttons on th +e form has been clicked:</b><br>***INSERT=$insert******DISPLAY=$displ +ay******CONFIR=$confir######<br>"; my $out_file; $out_file = "${curr_dir}table.html"; open(OUTPUT, "$out_file") || print "L40 - There is no file here, I'll +run away now!"; while(<OUTPUT>) { $_=~s/<!-- (\bMESS\b)\/\/ -->/$AoH{MESS}/g; print $_; } close OUTPUT; ####################################### ### Filter - Gets rid of characters that screw up the program. sub filter { if($_[0]){ $_[0]=~s/\s+$//; $_[0]=~s/\'/\\\'/g; $_[0]=~s/<//g; $_[0]=~s/>//g; $_[0]=~s/;//g; $_[0]=~s/\(//g; $_[0]=~s/\)//g; $_[0]=~s/\"//g; $_[0]=~s/\'//g; $_[0]=~s/\?//g; $_[0]=~s/\<script//g; #$_[0]=~s/\///g; $_[0]=~s/>//g; #$_[0]=~s/\%2F//g; return $_[0]; }else{ return ''; } } ### End Filter Sub


The HTML template code
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN""http://www.w3 +.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html> <head> <title>Test</title> </head> <body> Test<br> <form name="upf" method="post"> <input type="hidden" name="update" value="update"> <input type="submit" name="upf" value="Cancel" onClick="docum +ent.upf.action='test.pl';"> <br><br> <input type="submit" name="upf" value="Insert" onClick="docum +ent.upf.action='test.pl?insert=insert';"> <br><br> <input type="submit" name="upf" value="Confirm" onClick="docu +ment.upf.action='test.pl?confir=confir';"> </form> <!-- MESS// --> </body> </html>


Thanks a lot for the help!

Replies are listed 'Best First'.
Re: Passing Parameters Help!
by blazar (Canon) on Jul 11, 2007 at 08:05 UTC

    Three random comments:

    # Grab the current directory from $0. BEGIN { $0 =~ '(.*[\\\/])\w+\.\w+$'; $curr_dir = $1 || "./"; }

    Probably better approach than using FindBin, but then use File::Basename to get the actual dirname().

    my $display = &filter($q->param('display')) || '';

    Don't use the &-form of sub call: it is obsolete and likely not to do what you mean.

    sub filter { if($_[0]){ $_[0]=~s/\s+$//; $_[0]=~s/\'/\\\'/g; $_[0]=~s/<//g;

    While better ways to do the same altogether have been suggested to you, when you have to do so, avoid such long chains of =~'s:

    sub filter { my $str=shift; for ($str) { return '' unless $_; s/\s+$//; s/'/\\'/g; tr{<>;()\"\'?}{}d; s/<script//g; } $str; }
Re: Passing Parameters Help!
by moritz (Cardinal) on Jul 10, 2007 at 15:09 UTC
    Sorry, but your code is a mess, and no fun to debug.

    If you want to get the dir in which the script lies, use FindBin].

    If you call header() from CGI, you should actually send HTML - that starts with a doctype, <html> etc. - not with <br>.

    If you want to use proper HTML templates, consider using HTML::Template, Template, HTML::Template::Compiled or the like.

    If you want to escape "dangerous" characters, I recommend HTML::Entities.

    I assume that doesn't fix your original problem, but it might clean up your code significantly.

    BTW you are comparing "Insert" with "insert" - that will never work.

      If you want to get the dir in which the script lies, use FindBin].

      I used to be a fan of FindBin myself, but since I'm here I've discovered thanks to tye's excellent article and subsequent interventions that it is somewhat broken.

      If you want to use proper HTML templates, consider using HTML::Template, Template, HTML::Template::Compiled or the like.

      Lately, I'm "advertising" our fellow Rhandom's "new" Template::Alloy, because from what I read it seems very cool, and I'm enthusiast. But I realize this may get tiresome on the long run, so I won't do it any more... (Unless there are compellingly good reasons to do so!)

      If you want to escape "dangerous" characters, I recommend HTML::Entities.

      Well, since you rightly mentioned CGI, it is worth mentioning that it can do that too, sometimes automatically or by explicit (depending on the charset) use of escapeHTML().

Re: Passing Parameters Help!
by rpanman (Scribe) on Jul 10, 2007 at 17:32 UTC
    moritz and cool are both right. It is very difficult from your explanation to work out what behaviour you expect to have from your code. Using the modules moritz has listed would really help to tidy things up and make maintenance and fault finding more easy - as well as helping the monks to help you.

    Looking at you code, I guess you want to print the values of "insert", "display" and "confir" which are passed by your HTML template. Once this is done you want to open a file called "table.html" which is in the same directory as the script (you have not listed the contents of this file anywhere...). You then want to look at each line in this file and replace "<-- MESS// -->" with "OK your message has been received!" if the value of insert passed from your HTML form is equal to "insert"; otherwise you will replace "<-- MESS// -->" with "".

    I have assumed that "table.html" is your HTML template code. When I run your script from the command line I get:
    > perl mess.pl insert=insert display=test2 confir=test3 Content-Type: text/html; charset=ISO-8859-1 <br><b>I must to print these values here once the buttons on the form +has been clicked:</b><br>***INSERT=insert******DISPLAY=test2******CON +FIR=test3######<br><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Stric +t//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html> <head> <title>Test</title> </head> <body> Test<br> <form name="upf" method="post"> <input type="hidden" name="update" value="update"> <input type="submit" name="upf" value="Cancel" onClick="docum +ent.upf.action='test.pl';"> <br><br> <input type="submit" name="upf" value="Insert" onClick="docum +ent.upf.action='test.pl?insert=insert';"> <br><br> <input type="submit" name="upf" value="Confirm" onClick="docu +ment.upf.action='test.pl?confir=confir';"> </form> OK your message has been received! </body> </html>
    This looks like what you might expect. The html is badly formed though since the DOCTYPE declaration comes after you have already outputted some data... browsers will probably interpret it but you may want to tidy this up before going live with it.
      Yes, that's what I am expecting, just can't see where the problem is, and I did the same running like you did and it works, but doing from the browser I can't get the value of "insert" or from any of the parameters into the perl.
      Did you try running it from the browser?
        Okay. I've spent a while looking at this and now I'm going cross-eyed. I've got it working on my webserver after a bit of manipulation.

        I've modified the table.html file to the following:
        <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN""http://www.w3 +.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html> <head> <title>Test</title> </head> <body> <p>Test</p> <form method="get" action="/cgi-bin/test.pl"> <input type="hidden" name="update" value="Update"/> <input type="submit" name="cancel" value="Cancel"/> <input type="submit" name="insert" value="Insert"/> <input type="submit" name="confir" value="Confirm"/> </form> <!-- MESS// --> </body> </html>
        ... and changed the line:
        if($insert eq "insert"){
        to:
        if($insert eq "Insert"){
        The other change I made was to put the full path name into the $out_file line, like so:
        $out_file = "/opt/csw/apache/htdocs/table.html"; open(OUTPUT, "$out_file") || print "L40 - There is no file here, I'll +run away now!";
        My guess is that when you create the filename $out_file something is going wrong (perhaps you are pointing at the wrong directory, maybe the perl script and the html page are not in the same place), you then try to open the file which doesn't exist and so get the "L40" error message.

        You've been given a number of good options for correctly finding the path of the file and a number of recommendations for modules to make your life easier (the template modules for example) - it might be time to look at those more closely.
Re: Passing Parameters Help!
by cool (Scribe) on Jul 10, 2007 at 15:24 UTC
    Two suggestions for you (givin these after spending 20 odd mins debugging you code)
    1- Always be precise with your question, if you want proper attention towards your problem.
    2- Open an user account believe me,it will do good for you. And its free !!! :)
    Atleast follow the first one and come back, people will help you certaily. cheers :)
      I just dont know how such simple question can turn in such a sour answers

        It's not that the answers are sour. The question (at least from first glance) looks like:

         

        Terse ambiguous question

         

        Hideously long code and/or poorly formatted|organized code example

        It simply appears (at first glance) like you're not willing to do a little work to make it easy for the PMs to help you. The responses you got, rather than being sour, are simply bored pleas to the effect of Help me to help you with a little helpful advice tossed in for good measure. At least you had code with your question--too many petitioners don't even bother with that.

        If I see a question like this, I ignore it an move on to the next one unless:

      • It looks particularly interesting
      • It looks like I could learn something fun from it
      • I'm bored and have time to kill
      • Even in those cases, my reply with attempted solution would include admonishments to clarify the question, clarify|simplify the code, &tc.

        ...roboticus

        You're simple