Note: In the following three examples, I find it unnecessary to comment on the HTML generation functions and HTML text itself. This is such simple stuff it doesn’t warrant further explanation. I will, however, continue to comment on the deeper perl syntax.
Remember, don’t type the line numbers! They’re only here for reference.
1 #!/usr/bin/perl –w 2 3 use strict 4 use CGI::Carp qw(fatalsToBrowser); 5 use CGI qw(:standard); 6 my $sendmail_path = ‘/usr/lib/sendmail’; 7 my $to_email = ‘david@somehost.com’; 8 my $to_name = ‘David Nelson’; 9 my $email_subject = ‘Form Submission From The Web Site!’; 10 my $url = url; 11 my $mode = param(‘mode’); 12 if($mode eq ‘’) 13 { 14 print header, 15 start_html, 16 h2(‘Contact Us’), 17 start_form(-action=>$url, 18 -method=>’post’), 19 hidden(-name=>’mode’, 20 -value=>’send_email’, 21 -override=>1), 22 table( 23 Tr( [ 24 td( [ b(‘Your name’), textfield(‘your_name’) ] ), 25 td( [ b(‘Your email’), textfield(‘your_email’) ] ), 26 td( [ b(‘Your Comments’), textfield(‘your_comments’) ] ) 27 td( {-colspan=>2}, [ submit(‘Send Email’) ] ) 28 ] ) 29 ), 30 end_form, 31 end_html; 32 } 33 elsif($mode eq ‘send_email’) 34 { 35 my $email_body = param(‘your_comments’); 36 my $from_email = param(‘your_email’); 37 my $from_name = param(‘your_name’); 38 my $message = <<MESSAGE_SEPERATOR; 39 From: $from_email ($from_name) 40 Subject: $email_subject 41 To: $to_email ($to_name) 42 43 $email_body 44 MESSAGE_SEPERATOR 45 ($email_address =~ /(@.*@)|(\.\.)|(@\.)|(\.@)|(^\.)/ || $email_address !~ /^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,3}|[0-9]{1,3})(\]?)$/) { die(‘Invalid Email Address’) } 46 # the preferred way to do it 47 open (PIPE_TO_SENDMAIL, "| $sendmail_path –t oi”); 48 # some not so smart web hosts only let this work like the following: 49 #open (PIPE_TO_SENDMAIL, "| $sendmail_path –t”); 50 # some rather idiotic web hosts only let it work like this: 51 #open (PIPE_TO_SENDMAIL, "| $sendmail_path $email_address”); 52 print PIPE_TO_SENDMAIL $message; 53 close(PIPE_TO_SENDMAIL); 54 print header, 55 start_html, 56 h2(‘Email sent successfully to ‘ . param(‘your_email’)), 57 end_html; 58 } 59 else 60 { 61 print header, 62 start_html, 63 h2(‘Bad Mode Specified. Exiting…’), 64 end_html; 65 }
Line 1: Initialize the perl interpreter to run our program, and pass it the warn flag so we get good errors for debugging. Line 2: Always put an empty line after calling perl. Line 3: Enable more useful error messages for debugging. Line 4: Load the module that turns cryptic 500 Internal Server Errors into useful error messages we can read in a web browser. Line 5: Load the CGI module and import it’s functions, which saves us tons of time and effort in writing cgi scripts. Line 6: Define a scalar string variable that tells the program where the sendmail program is located on our system. If you don’t know where this is, ask your sysadmin or web hosting provider. Line 7: Define a scalar string variable we’ll use later for which email address to send this email to. Line 8: Define a scalar string variable we’ll use later for the name of the person we’re sending the email to. Line 9: Define a scalar variable called $email_subject, which will be what we send in the email’s Subject header. Line 10: Define a scalar variable called $url, and fill it with the value of CGI.pm’s url function, which we’ll use later to allow this script to reference itself. Line 11: Define the $mode scalar variable using CGI.pm’s param function, that we use to see which mode we’re going to process later. Line 12: Begin program logic by testing the $mode variable. If it doesn’t have a value, we’ll execute the code inside the following scope. Line 13: The opening bracket for the above if command. Begin the scope to execute if the if above evaluates to true. Line 14: Begin a multiline print statement that we’ll separate with commas. The first argument we pass to the print function is CGI.pm’s header function, which tells the web browser that an html document is coming at it. Lines 15-30: CGI.pm html generation functions are passed to the print statement we began on line 13. You could also have simply typed out pure html (enclosed in quotes as print usually works of course) here for the same effect. In our last script example, the tell a friend script, we simply print the HTML without CGI.pm’s functions. The benefit to using CGI.pm is that the form fields load with values from a previously submitted form automatically filled in. I recommend using the method of html generation that is easiest for you. Line 31: Here we end the multiline print statement we started on line 13 by passing a final argument to print, CGI.pm’s end_html function, which outputs the html needed to close an html document. We end this line with a semicolon, ending the print statement that began on line 13. Line 32: This closing bracket ends the if statement we began on line 11. Line 33: Here we begin an elsif statement to see if the $mode variable contains the value ‘send_email’. Line 34: The opening bracket for the above elsif statement. Line 35: Here we define a variable called $your_comments, and fill it’s value with the CGI.pm function param , which grabs the value of the html form element with the name of ‘your_comments’. Line 36: Here we define a variable called $from_email, and fill it’s value with the CGI.pm function param, which grabs the value of the html form element with the name of ‘your_email’. Line 37: Here we define a variable called $your_name, and fill it’s value with the CGI.pm function param , which grabs the value of the html form element with the name of ‘your_name’. Line 38: Begin a scalar variable that uses the multi-line print statement delimiter. This works just as if you were passing it to the print function, except that the text you enter into the multiline delimiter is stored in the scalar variable you specifiy, in this case $message. Line 39: This is the email From field. We then specify the email address and name of the person the email is coming from. Line 40: This is the email Subject field. We get the value for the $email_subject variable from when we defined it at line 9. Line 41: This is the email To field. We then specify the email address and name of the person the email is coming from. Line 42: This is a blank line, and MUST EXIST before we begin the body of the message. If you don’t have two line breaks before beginning the body of the message, your email will not send properly. VERY IMPORTANT! Line 43: This is the $email_body variable we defined above, which contains the body of the message to be sent. Line 44: This is the delimiter we use to close the multi line variable value assignment we started on line 38. Line 45: This is what is called a perl ‘regular expression’, and validates that the email conforms to the standard syntax for an email address. If it does not, the program exits with an error message. Line 46: This is a perl comment, and doesn’t do anything Line 47: This opens the sendmail program on our server, using a similar syntax as when we open a file. The difference is that we use what is a called a “pipe” to the sendmail program, which allow us to send data to the program. We pass the path of sendmail we defined earlier, and some parameters to the sendmail program. The –t tells sendmail to use the To field in the email to send the mail, and the oi are extra security related parameters that are wise to include. Not all web hosts will let you pass parameters to sendmail, so I’ve listed three different ways of invoking sendmail in this example. Line 48: Another perl comment Line 49: This opens a pipe to sendmail as well, and you should use this if the program did not work with the syntax outlined on line 46. This is a little less secure than the version on line 46, but we can only work with what our web hosting service gives us – it’s the best we can do. Line 50: Another perl comment. Line 51: This opens a pipe to sendmail as well, and you should use this if the program did not work with the syntax outlined on line 47 or line 49. This is MUCH less secure than the version on line 47, but we can only work with what our web hosting service gives us – it’s the best we can do. However, if it comes down to using this method, you need to be very careful to validate the $email_address variable using the syntax on line 46 to be sure someone is not trying to pass a rogue command to your server. Line 52: This prints the$message variable which contains the full email message we have built to the open sendmail pipe; Line 53: This closes the pipe to sendmail and effectively sends the message. Line 54: This begins a multiline print statement, passing as the first argument CGI.pm’s header function, which tells the web server that an html document is on its way out to the web browser. Line 55: Pass another argument to print, the CGI.pm function for generating the html code to begin an html document. Line 56: Pass one more argument to the print function, the CGI.pm function for generating an <h2> html tag. Pass the h2 function a string to notify the user that email was successfully sent, and to whom. We use string concatenation in the argument to the h2 function, so that we can print out the value of the CGI.pm function paraminside the <h2> tag as well. Line 57: End our multiline print function with the CGI.pm function to output the end of an html document. The semicolon tells perl to stop printing, which we began on line 54. Line 58: End the elsif statement with a closing bracket. We started this elsifstatement on line 33. Line 59: Begin an else statement, to catch the case where someone specified a bad mode, perhaps a cracker trying to hack our script and cause the server harm. Line 60: This begins a multiline print statement, passing as the first argument CGI.pm’s header function, which tells the web server that an html document is on its way out to the web browser. Line 61: Pass another argument to print, the CGI.pm function for generating the html code to begin an html document. Line 62: Pass one more argument to the print function, the CGI.pm function for generating an <h2> html tag. Pass the h2 function a string to notify the user that a bad mode was specified. Line 63: End our multiline print function with the CGI.pm function to output the end of an html document. The semicolon tells perl to stop printing, which we began on line 60. Line 61: This closing bracket tells perl we are finishing our else statement we started on line 59.
<-- Previous: CGI Script example: database insert and backend reporting (line by line code explanation) | Next: CGI Script example: redirection script (line by line code explanation) --> Please rate this cgi tutorial on cgi-resources.com: | ||