Data Helper, Inc. Development, Support, Configuration info at datahelper email address
Phone: 952.473.9344
Minnetonka, MN


 
 
Mailform.php - a (Somewhat) Secure Replacement for mailform.pl
Who Are We?
Who are You?
How Can We Help?
Talk to Us
Credits and Links
Tools and Toys
Site Map


Search This Site:

 
  Home PageWho are we?Who are you?How can We Help?Contact Us

The mailform.pl script is used by many Customer Response forms. It takes, as a parameter, the email address that the form is to be sent to. If you do not set it up carefully, it can be used by spammers to send emails to anyone.

We have created a PHP replacement to mailform.pl. The email address is "hard coded" in a script on your server, so it cannot be used to send email to arbitrary addresses. It is also flexible and easy to use.

First, copy the file "class.mailform.inc" into your PHP directory (which should not be in your HTML document tree!) The "class.mailform.inc" file, which defines the object MailForm is shown at the bottom of this page.

Next, create a PHP script that is in your document tree that will be the target of your mail form. We call ours "/scripts/mailform.php". The following example "hard codes" your TO email address, the email's subject, and the page that the visitor sees after the message is successfully sent or fails.

<?php
include( "class.mailform.inc" );
$mf = new MailForm"your.name@here.com""From the Mail Form" );
$mf -> SetOkUrl"/thanks.html" );
$mf -> SetBadUrl"/index.html" );
$mf -> GetStatstrue );
$mf -> ReadForm();
$mf -> Sendtrue );
?>

The form calls the above script to send the email. The form in your mail form page should look something line this:

<form name="guestbook" action="/scripts/mailform.php" method="post">
  <!--  The hidden inputs set the text descriptions for the fields
        in the email. -->
  <input type="hidden" name="desc[name]" value="Name">
  <input type="hidden" name="desc[addr]" value="Address">
  <input type="hidden" name="desc[hphone]" value="Evening Phone">
  <input type="hidden" name="desc[wphone]" value="Daytime Phone">
  <input type="hidden" name="desc[cphone]" value="Cell Phone">
  <input type="hidden" name="desc[email]" value="Email">
  <input type="hidden" name="desc[how]" value="Contact Preference">
  <input type="hidden" name="desc[comment]" value="Comments">
  <input type="hidden" name="retain_args" value="name,email">

    <table border="0" cellpadding="0" cellspacing="2" bgcolor="#eeeeee">
    <tr>
      <td>Name:</td>
      <td align="left"><input type="text" name="value[name]" size="42"></td>
    </tr>
    <tr>
      <td>Address:</td>
      <td align="left"><textarea name="value[addr]" cols="40" rows="3"></textarea></td>
    </tr>
    <tr>
      <td>Evening Phone:</td>
      <td align="left"><input type="text" name="value[hphone]" size="42"></td>
    </tr>
    <tr>
      <td>Daytime Phone:</td>
      <td align="left"><input type="text" name="value[wphone]" size="42"></td>
    </tr>
    <tr>
      <td>Cell Phone:</td>
      <td align="left"><input type="text" name="value[cphone]" size="42"></td>
    </tr>
    <tr>
      <td>Email:</td>
      <td align="left"><input type="text" name="value[email]" size="42"></td>
    </tr>
    <tr>
      <td>How do you prefer<br>to be contacted?</td>
      <td align="left"><input type="text" name="value[how]" size="42"></td>
    </tr>
    <tr>
      <td>Please enter Questions<br>and Comments here:</td>
      <td align="left"><textarea name="value[comment]" cols="40" rows="4"></textarea></td>
    </tr>
    <tr>
      <td colspan="2" align="center">
        <input type="submit" value="Send" name="submitButtonName">&nbsp;
        <input type="reset" value="Reset Form">
      </td>
    </tr>
  </table>
</form>

The PHP script in the first box above uses the following script:

<?php

// File:    class.mailform.inc
// Project: class MailForm
// Author:  Mark Willcox, Data Helper, Inc., www.datahelper.com
// Version: 1.0.2
// Update:  March 10, 2006

// License: Do whatever you want with this script, but I'd appreciate 
//          an email or a picture postcard from your home town.

// Yet another mail form.
// You can get everything from the FORM if you want. 
//  <form method="POST" action="mailform.php">
//  <input type="text" name="value[1]" ...
//  <input type="hidden" name="desc[1]" value="Work Phone">
//  <input type="text" name="value[2]" ...
//  <input type="hidden" name="desc[2]" value="Home Phone">
//  <input type="text" name="value[email]" ...
//  <input type="hidden" name="desc[email]" value="Email Address">
//  ...
//  <input type="hidden name="to" value="your.name@here.com">
//  <input type="hidden name="subject" value="From My Mail Form">
//  <input type="hidden name="stats" value="yes">
//  <input type="hidden name="ok_url" value "thanks.html">
//  <input type="hidden name="bad_url" value "try_later.html">
//  <input type="hidden name="retain_args" value "subject,1,email,whatever">
//  </form>

// In mailform.php:
// include( 'class.mailform.inc' );
// $mf = new MailForm();
// $mf->ReadForm();
// $mf->Send( true );

// Or better, create a script for your particular mail form and leave AT LEAST
// your email address off the form.
// In mymailform.php:
// include( 'class.mailform.inc' );
// $mf = new MailForm( 'yourname@here.com', 'From My Mail Form' );
// $mf->ReadForm();
// $mf->Send( true );

// Changes:
//   March 10, 2006 - Add retain_args tag.  List the keys of any values that you
//     want to send to your ok_url or bad_url.  You can reference them as
//     $_GET['email'] or wherever the value key is.
//     Thanks for the suggestion, Kjell Jarmlinger!

class MailForm
{
  
// These are the input tag variable names used in the form.  Change them if you must.
  
var $valueVar   'value';
  var 
$descVar    'desc';
  var 
$addrVar    'to';
  var 
$subjectVar 'subject';
  var 
$statsVar   'stats';
  var 
$okVar      'ok_url';
  var 
$badVar     'bad_url';
  var 
$retainArgsVar 'retain_args';
  
  
// Consider all the rest of the variables private to the class, OK?
  
var $formMethod 'POST';   // Can be 'GET', but 'POST' is much safer.
  
var $subject    'From the Data Helper Mail Form'// Can be overridden below.
  
var $stats;       // Want to add sender's IP address and domain to the email?
  
var $okUrl;       // Where do we go on success?
  
var $badUrl;      // Where do we go on failure?
  
var $retainArgs;  // Which input arguments do we want to send to the after-email redirects?
  
var $keySalt false// If set (setKey()), look for $_POST['key'] = md5( $keySalt . date('d h')) or last hour's.
  
var $key;
  
  var 
$addr;        // Your email address.
  
var $value;       // Array containing the things your customer typed on the form.
  
var $desc;        // Array of descriptions for each item in $value.
  
var $args;        // The build-up argument string for the ok or bad url redirect.
  
var $aliens;
  
  
// Constructor.
  
function MailForm$addr false$subject false$stats false )
  {
    
// Save your email address, the message subject, and the flag that requests
    // the IP address and domain to be quietly added to the email.
    
$this->addr $addr;
    
$this->stats $stats;
    
    
// Only override the subject if we have one on the constructor call.  Otherwise, 
    // use the default.  We NEED some subject.
    
if( $subject )
      
$this->subject $subject;
    
    
// This isn't necessary, but I like to be explicit.
    
$this->okUrl  false;
    
$this->badUrl false;
    
$this->value  false;
    
$this->desc   false;
    
$this->okUrl  false;
    
$this->badUrl false;
    
$this->retainArgs false;
    
$this->args '';
    
    
$this->aliens = array( 
      
'92.113.0.0/255.255.0.0'
      
'94.176.0.0/255.252.0.0'
      
'94.124.0.0/255.255.0.0'
      
'91.124.0.0/255.255.0.0'
    );
  }

  
// Scrape all the data from the form.
  
function ReadForm()
  {
    if( 
$this->formMethod == 'POST' )
      
$vars $_POST;
    else
      
$vars $_GET;
    
    
// Only store values that we don't already have.
    
if( ! $this->addr )
      
$this->addr $vars$this->addrVar ];
      
    if( ! 
$this->subject )
      
$this->subject $vars$this->subjectVar ];
      
    if( ! 
$this->okUrl )
      
$this->okUrl $vars$this->okVar ];
      
    if( ! 
$this->badUrl )
      
$this->badUrl $vars$this->badVar ];
      
    if( ! 
$this->stats )
      
$this->stats = isset( $vars$this->statsVar ] );
    
    if( ! 
$this->value )
      
$this->value $vars$this->valueVar ];
          
    if( ! 
$this->desc )
      
$this->desc $vars$this->descVar ];
          
    if( ! 
$this->retainArgs )
      
$this->retainArgs $vars$this->retainArgsVar ];
    
    
$this->key $vars['key'];
  }
  
  
// Send yourself an email.  If $redirect is true (default), a page will be redirected
  // to the browser that sends the visitor to the OK or BAD page.  If you call
  // Send( false ), you will have to determine what to do next.
  
function Send$redirect true )
  {
    
defineNL"\n" );
    
    
// Prepare the retainArgs variable.  Give it surrounding commas to make the  strstr work.
    
if( ! $this->retainArgs $this->retainArgs '';
    
$this->retainArgs str_replace( array( ' ', ), array( '', ), $this->retainArgs );
    
$this->retainArgs "," $this->retainArgs ",";
    
    if( 
strstr$this->retainArgs'subject' ))
    {
      
$this->args "subject=" urlencode$this->subject );
    }
    
    
// Set up the email headers.
    
$headers  'Date: ' date'r' ) . NL;
    
$headers .= 'From: Mail Form <' $this->addr '>' NL;
    
    
// Set up the email.
    
$msg '';
    
$subjectLine '';
    if( 
$this->subject )
      
$subjectLine $this->subject NL NL;

    
// For each of the boxes that the visitor filled in, put the description
    // of the box and the visitor's text into the message. 
    
foreach( $this->value as $key => $value )
    {
      
$value str_replace"\r"' 'trim$value ));
      
      if( 
strlen$value ) > )
      {
        
// The description is optional.
        
if( isset( $this->desc[$key] ))
          
$msg .= $this->desc[$key] . ':' NL;
        
$msg .= $value NL NL;

        if( 
strstr$this->retainArgs$key ))
        {
          if( 
strlen$this->args ) > )
            
$this->args .= "&";
          
$this->args .= urlencode$key ) . "=" urlencode$value );
        }
      }
    }
    
    
// Do you want to capture the visitor's IP address and domain?
    
if( $this->stats )
    {
      
$ip $_SERVER['REMOTE_ADDR'];
      
$sender 'From: ' gethostbyaddr$ip ) . ' (' $ip ')' NL;
    }

    
$isBadRequest false;

    
// Is this coming from some spammy IP address?
    
$ip $_SERVER['REMOTE_ADDR'];
    
$ip explode'.'$ip );
    
$ip = ($ip[0]*16777216) + ($ip[1]*65536) + ($ip[2]*256) + ($ip[3]);
    foreach( 
$this->aliens as $alien )
    {
      if( ! 
$isBadRequest 
      {
        
$alien explode'/'$alien );
        
$mask explode'.'$alien[1] );
        
$alien explode'.'$alien[0] );
        
        
$alien = ($alien[0]*16777216) + ($alien[1]*65536) + ($alien[2]*256) + ($alien[3]);
        
$mask = ($mask[0]*16777216) + ($mask[1]*65536) + ($mask[2]*256) + ($mask[3]);
        
        
$isBadRequest = ($ip $mask ) == ($alien $mask );
      }
    }

    
// Now let's see if this is spam...
    
if( (! $isBadRequest) && $this->keySalt ) {

      if( 
$this->key != md5$this->keySalt date('d h'))) {
        if( 
$this->key != md5$this->keySalt date('d h'strtotime('-1 hour')))) {
          
$isBadRequest true;
        }
      }
    }

    
// If there's anything in the message, send it.
    
if( ! $isBadRequest )
    {
      if( (! empty( 
$msg )) && ( $this->addr )) {
        if( 
$this->value['name'] ) {
          
$this->subject .= ': ' $this->value['name'];
        }
        
$result mail ($this->addr$this->subject
          
$subjectLine $msg $sender$headers );
      }
    }
    
    
// If desired, send the visitor to the OK or BAD page.
    
if( $redirect  )
    {
      
$url $result $this->okUrl $this->badUrl;
      if( 
$url )
        
$this->_redirect$url );
    }
      
    return 
$result;
  }
  
  
// Set the hash of values.  This can be used to add some fields to the email.
  
function SetValues$value )
  {
    
$this->value $value;
  }
  
  
// Set the hash of descriptions of values.  
  // This can be used to add some fields to the email.
  
function SetDesc$desc )
  {
    
$this->desc $desc;
  }
  
  
// Set YOUR email address.  This is the TO: address on the email.
  
function SetAddr$addr )
  {
    
$this->addr $addr;
  }
  
  
// Set the email subject.
  
function SetSubject$subject )
  {
    
$this->subject $subject;
  }
  
  
// Set the page that the visitor goes to on success.
  
function SetOkUrl$okUrl )
  {
    
$this->okUrl $okUrl;
  }
  
  
// Set the page that the visitor goes to on failure.
  
function SetBadUrl$badUrl )
  {
    
$this->badUrl $badUrl;
  }
  
  
// Set the key salt that will be used to see if this is a valid request, not a spam..
  
function SetKey$keySalt )
  {
    
$this->keySalt $keySalt;
  }
  
  
// Turn on the switch so the visitor's IP address and domain are added to the email.
  
function GetStats$stats true )
  {
    
$this->stats $stats;
  }
  
  
// The form uses GET rather than POST.  (Not recommended!)
  
function MethodGET$get true )
  {
    
$this->formMethod $get 'GET' 'POST';
  }

  
// This puts out a whole page.  If you are redirecting, don't output anything else.
  
function _redirect$url )
  {
    
$args $this->args;
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head >
<title>Form Sent</title>
<meta http-equiv="refresh" content="5;URL=<?php echo "$url?$args"?>">
</head>
<body>

<center>
<p>I am trying to send you back after your response form.
<p>If you don't get back in a a few seconds, press the "Continue" button below.
<p><form action="<?php echo "$url?$args"?>" method="post">
    <input type="submit" name="Continue" value="Continue">
</form>
<script language="JavaScript">
window.location.replace('<?php echo "$url?$args"?>');
</script>
</body>
</html>
<?php
  
}
}
?>

You can use the same script for more than one form, emailing each form to a different person. Add a tag to your form like this:
<input type="hidden" name="to" value="George">
where "George" is an identifier for the form recipient, not the email address. Then replace the script in the first box at the top of this page with one like this:

<?php
include( "class.mailform.inc" );

// Get the reply redirects from the form
$good $_POST["ok_url"];
$bad $_POST["bad_url"];

// Get the email address from the "to" parameter.
switch( $_POST["to"] )
{
case 
"George":
  
$addr "george@jetson.com";
  
// George doesn"t send the redirect addresses in the form.
  
if( ! isset( $good ) )
    
$good "http://www.jetson.com/thanksForEmail.phtml";
  if( ! isset( 
$bad ) )
    
$bad "http://www.jetson.com/badSend.phtml";
  break;
case 
"Fred":
  
$addr "fred@flintstone.com";
  
// Fred always sends the redirect addresses in the form.
  
break;
default:
  
// Always send the email somewhere.
  
$addr "info@whatever.com";
  if( ! isset( 
$good ) )
    
$good "http://www.whatever.com/thanksForEmail.phtml";
  if( ! isset( 
$bad ) )
    
$bad "http://www.whatever.com/badSend.phtml";
  break;
}

// If no redirect address is found, send the visitor to the site"s home page.
if( ! isset( $good ) )
  
$good "/";
if( ! isset( 
$bad ) )
  
$bad "/";

// You could change this to get even the email subject from the form.
$mf = new MailForm$addr"From the Web Mail Form" );
$mf -> SetBadUrl$bad );
$mf -> SetOkUrl$good );
$mf -> GetStatstrue );
$mf -> ReadForm();
$mf -> Sendtrue );
?>