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

Hello, Monks. This is what I'm using to un-webby-fy data from a web form:
if ($ENV{'REQUEST_METHOD'} eq 'POST') { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $FORM{$name} = $value; }
However, I'm having trouble when the user doesn't fill out all the fields. Then in the email to the administrator:
open (MESSAGE,"| /usr/lib/sendmail -t"); print MESSAGE "To: $FORM{submitaddress}\n"; print MESSAGE "From: $FORM{name}\n"; print MESSAGE "Reply-To: $FORM{email}\n"; print MESSAGE "Subject: Faculty Bibliography Submission\n\n"; print MESSAGE "The following information was submitted from $FORM{ +name} at $FORM{email}:\n\n"; print MESSAGE "Full Name: $FORM{name}"; print MESSAGE "\n"; print MESSAGE "Publication Name: $FORM{pubname}"; print MESSAGE "\n"; print MESSAGE "Other Authors: $FORM{otherauthors}"; print MESSAGE "\n"; print MESSAGE "Other Editors: $FORM{othereditors}"; print MESSAGE "\n"; print MESSAGE "Main Publication Title: $FORM{pubtitle}"; print MESSAGE "\n"; . . . . close (MESSAGE);
It does not put in the new lines if the user did not fill in a particular field. A new line is only created if there was something entered. My guess is that I need to check for the null (undef??) fields when I un-webby-fy and put a new line "\n" in it instead of leaving it blank. However, my limited perl knowledge keeps me from doing so. Thank you thank you thank you for your help/advice. It would be great if you could e-mail any replies to me as well at elizabeth.dahm@hope.edu

Replies are listed 'Best First'.
Re: checking for null variables
by hardburn (Abbot) on Apr 15, 2003 at 18:29 UTC

    Do not parse CGI input data by hand. There is a perfectly good module that does it for you. Example:

    use CGI qw(:standard); my $param1 = param('param1'); my $param2 = param('param2'); if(! defined($param1) ) { # Run the following code if $param1 is null die "param1 is null!\n"; } if(! defined($param2) ) { # Run the following code if param2 is null die "param2 is null!\n"; }

    Update: Added :standard import for CGI.pm, as per merlyn's suggestion (oops).

    ----
    I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
    -- Schemer

    Note: All code is untested, unless otherwise stated

Re: checking for null variables
by crouchingpenguin (Priest) on Apr 15, 2003 at 18:41 UTC

    hmm... you might wanna reuse existing solutions such as CGI and Net::SMTP. Untested code:

    #!/usr/bin/perl use strict; use warnings; use CGI; use Net::SMTP; use vars qw( $cgi %FORM $smtp ); ### get the cgi params $cgi = new CGI(); map { $FORM{$_} = $cgi->param($_) } $cgi->param(); ### and on and on ... unless ( defined($FORM{PARAM1}) && defined($FORM{PARAM2}) ){ #complian } ### smtp stuff $smtp = Net::SMTP->new('mailhost'); $smtp->mail($FORM{FROM_EMAIL}); $smtp->to($FORM{TO_EMAIL}); $smtp->data(); $smtp->datasend("To: $FORM{TO_EMAIL}\n"); $smtp->datasend("Subject: $FORM{SUBJECT}\n"); $smtp->datasend("\n"); my $msg = qq( The following information was submitted from $FORM{NAME} at $FORM{EMAI +L}: Full Name: $FORM{name} Publication Name: $FORM{pubname} Other Authors: $FORM{otherauthors} Other Editors: $FORM{othereditors} Main Publication Title: $FORM{pubtitle} ); $smtp->datasend($msg); $smtp->dataend(); $smtp->quit; + 1;

    Update:Thanks VSarkiss
    Update:I think the untested speaks for itself. This is an example and nothing more. =]


    cp
    ----
    "Never be afraid to try something new. Remember, amateurs built the ark. Professionals built the Titanic."
      Ahh yes, my common rant in "cgi-to-email" solutions. Your form can be used to send spam. Please do not deploy this code on the world-wide web until you have ensured that you do not get delivery addresses from form data. Otherwise, when someone discovers that your form sends email, they'll exploit it for spamming, and you'll get the blame, and then your system will be RBL'ed, and you'll end up hating the world, or something like that.

      -- Randal L. Schwartz, Perl hacker
      Be sure to read my standard disclaimer if this is a reply.

        I appreciate your comment, but, as you can tell, I am a perl novice and know of no solution. Could you recommend a good tutorial to me? I was using the one at htmlgoodies.com

      use CGI qw(:standard); # later... $cgi = new CGI(); map { ... } $cgi->param();
      There is no reason to do both. The :standard allows you to use most of the routines in CGI as standalone functions, but you're using the "OO" style calls, which don't require the function names to be imported to your code.

      In other words, do either:

      use CGI; $cgi = CGI->new(); # my preference
      or:
      use CGI qw(:standard); map { ... } param();

Re: checking for null variables
by Improv (Pilgrim) on Apr 15, 2003 at 19:17 UTC
    This is completely unrelated to your primary problem, which people have apparently already helped you with. You might want to consider improving the style of your code. Firstly, there's no need to have those newlines in their own print statements -- instead you might try:
    print MESSAGE "Full Name: $FORM{name}\n";
    
    Secondly, you might want to bunch all those prints together into a single big print with a here document. It might look like this:
    print MESSAGE <<EOMSG; To: $FORM{submitaddress} From: $FORM{name} Reply-To: $FORM{email} Subject: Faculty Bibliography Submission The following information was submitted from $FORM{name} at $FORM{emai +l}: Full Name: $FORM{name} Publication Name: $FORM{pubname} Other Authors: $FORM{otherauthors} Other Editors: $FORM{othereditors} Main Publication Title: $FORM{pubtitle} EOMSG
    Finally, an alternative might be to make the generation of the form even more dynamic:
    $longform{name} = "Full Name"; $longform{pubname} = "Publication Name"; ... foreach my $form (keys %longform) { print MESSAGE "$form: $longform{$form}\n"; } ...
    The downside to the last idea, of course, is that you lose control over the ordering. Hopefully these ideas will be useful...
      The downside to the last idea, of course, is that you lose control over the ordering.

      Unless, of course, you keep your ordering in some @ordering array. Then, your loop looks something like:

      my %longform ... $longform{name} = 'Full Name'; $longform{pubname} = 'Publication Name'; ... my @ordering = qw( name pubname ... ); foreach my $form (@ordering) { print MESSAGE "$form: $longform{$form}\n"; } ...
      (Style nit - don't use double-quotes unless you need them. Single-quotes tell me, the maintainer, that this is a constant string. Double-quotes tell me it could change.)

      ------
      We are the carpenters and bricklayers of the Information Age.

      Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

      Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.