I am a web designer and client-side developer living in Brooklyn, NY and working at HUGE.

Another PHP Contact Form Script

December 14, 2006 I'm done here, let's go home …

Please note that this article is somewhat old and no longer represents what is used on this site. I wouldn't do everything the same way. Maybe I'll rewrite it sometime.

Just what the world needs. Another PHP-based contact form script!

I know, I know. There's a million of these out there. But this is the one I use on my web design and development portfolio.

This is a pretty straightforward script, built in PHP, that takes input from a run-of-the-mill XHTML form, checks it for various anomolies (looking mostly for spam bots) and sends a plain text email as needed.

I'll go through this one chunk at a time and then post a link to a source file you can use free of charge and without attribution. However, it would be nice if I knew it helped someone, so feel free to comment or send me an email.

Certain items (the $to variable, for instance) have been changed to protect the innocent (that's me!).

One note: anytime you see a », it denotes a line break created for spacing issues.

First thing we'll do is set things up:

$thisPage = "contact";
$pageTitle = "Contact Me";
include "includes/head.php";
include "includes/nav.php";

$to="[YOUR EMAIL ADDRESS HERE]";
$showForm=true;

This initializes several variables and includes the PHP files that make up the header and global navigation on the site. The variables $thisPage and $pageTitle pass certain parameters to the included files. We won't worry about them. The last two variables - $to and $showForm - are the important ones.

$to will be the email where the processed form results will be sent (don't worry, since PHP is a server-side language, no one will ever be able to view it!). $showForm controls whether or not the form is rendered in XHTML.

if (!isset($_POST["submit"])){
  echo "\n        <p>Please feel free to use the form below to send me an email. I promise I'll respond as soon as I'm able.</p>";
} else {
  $name     = $_POST['name'];
  $name     = urldecode($name);
  $email    = $_POST['email'];
  $url      = $_POST['url'];
  $message  = $_POST['message'];
  $math = $_POST['math'];
  $subject  = "Portfolio Email Form";
  $headers  = "From: $name \n";
  $headers .= "Reply-To: $email";
			

Here, we first check whether or not the $_POST variable has been set (that is, if someone has clicked the "submit" button). If not, it spits out the generic intro text. If so, we start processing variables provided by the form.

$name, $email, $url, and $message are all provided in the $_POST variable by the form and assigned to shorter variable names. $name is decoded to remove special characters that spam bots might use to inject email headers.

Finally, we begin constructing the message headers by defining $subject (the subject line of the email) and $headers which will give us - you guessed it - email headers.

  if (!empty($math)) {
    if ($math != '15') {
      $math = strtolower($math);
    }
  }

  if (empty($name) || empty($email) || empty($message) || empty($math)) {
    echo "\n        <h3>Error!</h3>";
    echo "\n        <p>Uh oh!  Looks like you missed one of the required fields.  Please, try again.</p>";
  }
  elseif ($math != '15' && $math != 'fifteen') {
    echo "\n        <h3>Check Your Math</h3>";
    echo "\n        <p>You didn't answer the math question correctly.  It's not hard...unless you're a spambot.</p>";
  }
  elseif (eregi("\r",$name) || eregi("\n",$name) || eregi("\r",$email) || eregi("\n",$email) || eregi("\r",$url) || eregi("\n",$url)) {
    echo "\n        <h3>Error!</h3>";
    echo "\n        <p>Tsk, tsk!  Seems as though you're trying to inject some email headers.  That's not very nice.</p>";
  }
  elseif (!eregi('^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*@(([0-9a-zA-Z])+([-\w]*[0-9a-zA-Z])*\.)+[a-zA-Z]{2,9})$', $email)) {
    echo "\n        <h3>Error!</h3>";
    echo "\n        <p>Strange.  It seems you've entered an invalid email address.  Please, try again and check for typos!</p>";
  }
  else {
    $full_message = "$message\n\nFrom: $name\nEmail: $email\nURL: $url";
    mail ($to, $subject, $full_message, $headers);
    echo "\n        <h3>Success!</h3>";
    echo "\n        <p>Your email was successfully sent!</p>";
    echo "\n        <p>I will respond to your message as soon as possible. Thank you for your interest in me and my work.</p>";
    $showForm = false;
  }
}
			

This code does a number of things. Through the if/elseif/else statements, it performs various checks of the input variables that were defined in the previous chunk of code.

The variable $math determines if the mathematical question provided in the form is defined, then if it is defined, it checks to see if the input was a number string or a alphabetic character string and, if it was alphabetic, sets all characters to lower case. In other words, if the input is correct (15) and typed "Fifteen" or "FIFTEEN" or even "FiFteEN" it becomes "fifteen". Of course, if it's wrong, it still sets it to lower case. We'll check this for correctness later.

The first check is to see if any of the variables in question ($name, $email, $message, or $math) are empty or haven't been provided. If any are empty, it returns an error and re-renders the form.

Next, it checks the validity of the answer to the mathematical question ($math) in the case of this example script, the answer is either "15" or "fifteen" (remember, it was lowercased earlier!).

Third, it checks to see if there are any "\n" or "\r" characters, which denote new lines or carriage returns - a common tactic for injecting headers into email scripts. If any are found, it returns an error.

Fourth, it uses a regular expression to analyze $email to make sure it's a valid email address and returns an error if it isn't.

Finally, if all the above checks pass, it generates the full email and sends it using PHP's built-in mail function, returns a notification that the mail was sent and doesn't re-render the form.

The final part of the script:

if ($showForm) { ?>
        <form id="contactForm" method="POST" action="<?=$_SERVER['PHP_SELF'];?>">
          <div class="clearfix">
            <label for="name">Name <span> (<abbr title="Required">Req'd</abbr>)</span></label>
            <input type="text" name="name" id="name" class="text" value="<?php echo $name; ?>" />
          </div>
          <div class="clearfix">
            <label for="email">Email <span> (<abbr title="Required">Req'd</abbr>)</span></label>
            <input type="text" name="email" id="email" class="text" value="<?php echo $email; ?>" />
          </div>
          <div class="clearfix">
            <label for="url">Website </label>
            <input type="text" name="url" id="url" class="text" value="<?php echo $url; ?>" />
          </div>
          <div class="clearfix">
            <label for="message">Message <span> (<abbr title="Required">Req'd</abbr>)</span></label>
            <textarea rows="10" cols="30" name="message" id="message"></textarea>
          </div>
          <p>Please answer the following math question.  This is to prevent spam bots from automatically filling out this form.</p>
          <div class="clearfix">
            <label for="math">What is five times the square root of nine? <span> (<abbr title="Required">Req'd</abbr>)</span></label>
            <input type="text" name="math" id="math" class="text" value="" />
          </div>
          <div><input type="submit" name="submit" value="Send" id="send" class="button" /></div>
        </form>
<?php
  }
  include "includes/sub1.php";
  include "includes/footer.php";
?>

This is the form itself. Remember the $showForm variable? If that's set to true (as it is by default), it renders the form.

Two things to note on the form are the action="<?=$_SERVER['PHP_SELF'];?>" and the values of certain inputs. The action attribute of the form tells it that the form should be processed by this script. The value attributes are used to restore old values should the form be re-rendered.

Finally, specific to my web design and development portfolio are two more includes that pull in the rest of the XHTML page.

That's about it. Feel free to use this script without attribution. However, it would be nice if I knew it helped someone, so feel free to comment or send me an email!

  1. Download the full script!

After downloading the file, change the extension to .php, not .phps!

Other Articles

  1. PHP Twitter Feed Class

    October 20, 2008

    When I was building this site, I wanted to include a Twitter feed. I didn't want to bother with signing up for their API or anything and their "badges" didn't cut it - I didn't want to rely on JavaScript to show the feed. So, I decided to write a PHP class to grab that data. And now I'm sharing it!

    Continue reading …
  2. Facile Forms Framework

    January 29, 2008

    I've marked up quite a few HTML forms in my day. On complex sites, the problem often becomes maintaining a consistent presentation of form elements across a variety of pages, columns widths, and so on.

    Continue reading …
  1. Using CSS to Target Multiple Internet Explorer Versions

    January 10, 2007

    I thought I'd share my method of targeting CSS fixes for multiple versions of Internet Explorer in light of IE7's recent release. It's a two-pronged approach combining Microsoft's proprietary Conditional Comments and various CSS filters.

    Continue reading …
  2. Another PHP Contact Form Script

    December 14, 2006

    Just what the world needs. Another PHP-based contact form script! I know, I know. There's a million of these out there. But this is the one I use on my web design and development portfolio.

    Continue reading …
  3. Movin' On Up

    January 8, 2006

    After 16 months at Oklahoma State University, I'm leaving to pursue new employment. As of January 17th, I'll no longer be an OSU employee and will begin working full-time for my father's company, O'Neill Marketing Communications. Part of my work week will be sub-contracted to Nomadics, Inc. ICx Technologies where I've been hired to complement their marketing team on a part-time basis.

    Continue reading …