PHP Contact Form Tutorial

May 25th, 2010 Leave a comment 3 comments
Like the article?
PHP Form

Many web sites are opting to use a contact form to allow its visitors to communicate. This is larger due to the prevalence of spam bots which harvest email addresses from web sites. In this tutorial, we’re going to build a simple contact form in PHP.

This is going to be a pretty simple contact form. We’ll be using a single PHP file to display the form and to process it. This simplifies things quite a bit. Ready? Let’s get started.

Step One: Creating the Form

The first step is to create some HTML markup for our form. For this tutorial, we’re going to ask the user to give us their email address, name, a subject line and a message. Create a file named contact.php or whatever you want to call your form. Using a PHP file for this allows us to add PHP code to the file. In the later steps, we’ll be adding the code to process this form so that one file handles the entire process. Additionally, we’re going to use the $_SERVER variable to get the name of the current file. We will use that to supply the action parameter to our form tag in order to make sure the form gets submitted to the same page that generated it. Here is our initial markup:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; 
charset=iso-8859-1" />
<title>PHP Contact Form Demo</title>
</head>
<body>
<h1>Contact Form Demo</h1>
<form method="POST" action="<?php echo $_SERVER['PHP_SELF']; ?>" id="contactform">
<fieldset>
<legend>Contact Form</legend>
<ol>
<li><label for="Email">Email: </label><input 
id="id_email" type="text" name="email"/></li>
<li><label for="Name">Name: </label><input 
id="id_name" type="text" name="name"/></li>
<li><label for="Subject">Subject: </label><input 
id="id_subject" type="text" name="subject"/></li>
<li><label for="Message">Message:</label><textarea id="id_message" rows="10" cols="40" name="message"></textarea></li>
</ol>
</fieldset>
<p><input type="submit" class="button" 
id="id_submit" name="submit" value="Send Message" /></p>
</form>
</body>
</html>

Step Two: Style the Form

If you have been following along yourself, this form is not very attractive. Additionally, the use of a numbered list causes extra numbers to appear which might be confusing, especially to someone using a screen reader. We are going to define some CSS to make this form much more appealing. For this tutorial, I am going to put the styles in the <head> section of my HTML but usually, I would put these in a separate stylesheet and add it with the following:

<link rel="stylesheet" type="text/css" href="[filename of stylesheet]" />

Under the <title> tags, we’re going to insert the following:

<style type="text/css">
body {
  font-family: Arial, Helvetica, sans-serif;
}

fieldset { 
  margin-top: 1.5em; 
  padding-bottom: 1em;
  border:1px solid #000000; 
  background-color: #eeeeee;
}

legend {
  font-weight: bold; 
  margin-left: 1em;
}

fieldset ol {
  list-style: none; 
  padding: 1em 1em 0 1em;
}

fieldset li {
  padding-bottom: .5em
}

fieldset p {
  margin: 1em 0 1em;
}

label {
  display: block; 
  line-height: 1.8em;
  vertical-align:top;
}

<!--[if lte IE 7]>
legend {
  position: relative; 
  top: -0.5em; z-index: 0;
}

fieldset {
  position: relative;
}
<![endif]-->
</style>

Let’s look at some of the more important aspects of this code. The fieldset ol selector allows us to style the numbered list within the fieldset. This is how we remove the numerals next to each field. In this case, we apply list-style: none to remove the numerals. Also notice that for the label elements we’re setting display: block. This forces each of the field labels to be on a line by itself and puts the form fields under each label.

The final part of this code that is interesting is the section under <!–[if lte IE 7]>. This is a conditional tag that defines styles that will only be applied to Internet Explorer version 7 or less. In particular, we add some positioning to the legend on IE because the default position is too high.

Step Three: Process the Form

Now, we are going to add some PHP code to process the form and email the results. The code we are using here is based on this excellent article. At the beginning of your file, before the DOCTYPE statement, insert the following code:

<?php
if (isset($_POST['submit'])) {
	if (trim($_POST['email'] == '')) {
		$hasError = true;
	} else if (!eregi("^[A-Z0-9._%-]+@[A-Z0-9._%-]+.[A-Z]{2,4}$",trim($_POST['email']))) {
		$hasError = true;
	} else {
		$email = trim($_POST['email']);
	}

	if (trim($_POST['message'] == '')) {
		$hasError = true;
	} else {
		$message = trim($_POST['message']);
	}

	if (trim($_POST['name'] == '')) {
		$hasError = true;
	} else {
		$name = trim($_POST['name']);
	}

	if (trim($_POST['subject'] == '')) {
		$hasError = true;
	} else {
		$subject = trim($_POST['subject']);
	}

	if (!isset($hasError)) {
		$emailTo = 'youremail@yoursite.com';
		$body = "Name: $name nnEmail: $email nnSubject: $subject nn Message: $message nn";
		$headers = 'From: My Site <'.$emailTo.'>'."rn" .'Reply-To: '. $email;
		mail($emailTo, $subject, $body, $headers);
		$emailSent = true;
	}
}
?>

Let’s take a look at how this works. First, we check the $_POST array which gets set with the fields from a form when the server receives a posted form. In this case, we are testing for the “submit” key which will only get set if the user clicked the submit button at the bottom of the form. If this variable exists, then we know that we are going to need to process the form. If it is not set, then we skip all the form processing code and output the form itself.

Next, we look at the required fields for the form and make sure that the $_POST variable does not contain an empty string. If a field is missing, we set $hasError to True. This will be useful later. We also use a regular expression to make sure that the email address looks like a valid address. Basically, our regular expression looks for 1 or more digits, letters or the _ or % followed by the @ sign followed by 1 or more letters or digits followed by a period and 2 or 3 letters. If the email does not appear to be in a valid format, we again set $hasError to True.

Finally, we look at $hasError to see if the form passed validation. If $hasError is false it means that everything looks OK with our form. The next several lines prepare the message body and headers and finally send an email with the content of our contact form. After we send the email, we set the variable $emailSent to True. We will revisit this later.

Step Four: Provide User With Feedback

We are doing pretty good so far, but what happens if the user does not set a required field. If there is an error, we want to let the user know so they can fix it and try again. Also, once the form is submitted and the contents emailed away, this script does not tell the user. Instead, it just shows the form again. We do not want someone to keep trying to resubmit the same message so let’s give the user some feedback. We are going to insert the following code under the <h1> heading in the form portion itself.

<?php
if(isset($hasError)) { ?>
	<p class="error">Please check if you've filled all the fields with valid information. Thank you.</p>
<?php } ?>

<?php
if(isset($emailSent) && $emailSent == true) { ?>
	<p><strong>Email Successfully Sent!</strong></p>
	<p>Thank you <strong><?php echo $name; ?></strong> for using my contact form! Your email was successfully sent and I will be in touch with you soon.</p>
<?php } else { ?>
	<form method="POST" action="<?php echo $_SERVER['PHP_SELF']; ?>" id="contactform">
	<fieldset>
	<legend>Contact Form</legend>
	<ol>
	<li><label for="Email">Email: </label><input id="id_email" type="text" name="email"/></li>
	<li><label for="Name">Name: </label><input id="id_name" type="text" name="name"/></li>
	<li><label for="Subject">Subject: </label><input id="id_subject" type="text" name="subject"/></li>
	<li><label for="Message">Message:</label><textarea id="id_message" rows="10" cols="40" name="message"></textarea></li>
	</ol>
	</fieldset>
	<p><input type="submit" class="button" id="id_submit" name="submit" value="Send Message" /></p>
	</form>
<?php } ?>

To close out the script and prevent a syntax error, we need to add this snippet of code after the </form> tag and before the closing body tag </body>.

This code is pretty simple. First of all, directly under the heading, we are going to check and see if the $hasError variable got set. This will only return true if at some point during processing the form, we set $hasError to true. Otherwise, this will return false. If it is true, our code displays a handy error message. While our error message does not give any details or narrow the error down, at least the user knows that an error did occur and that their message has not been sent.

Next, we test and see if the $emailSent variable has been set. This only occurs if we send a message from the user. In this case, we’ll display a thank you message and let them know that they do not need to resubmit the form because their message has been sent.

Final Code

Your final code should look like the following:

<?php
if (isset($_POST['submit'])) {
	if (trim($_POST['email'] == '')) {
		$hasError = true;
	} else if (!eregi("^[A-Z0-9._%-]+@[A-Z0-9._%-]+.[A-Z]{2,4}$",trim($_POST['email']))) {
		$hasError = true;
	} else {
		$email = trim($_POST['email']);
	}

	if (trim($_POST['message'] == '')) {
		$hasError = true;
	} else {
		$message = trim($_POST['message']);
	}
        
	if (trim($_POST['name'] == '')) {
		$hasError = true;
	} else {
		$name = trim($_POST['name']);
	}
        
	if (trim($_POST['subject'] == '')) {
		$hasError = true;
	} else {
		$subject = trim($_POST['subject']);
	}

	if (!isset($hasError)) {
		$emailTo = 'youremail@yoursite.com';
		$body = "Name: $name\n\nEmail: $email\n\nSubject: $subject\n\nMessage: $message\n\n";
		$headers = 'From: My Site <'.$emailTo.'>'."\r\n" .'Reply-To: '. $email;
		mail($emailTo, $subject, $body, $headers);
		$emailSent = true;
	}
}
?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
	<title>PHP Contact Form Demo</title>
<style type="text/css">
body {
  font-family: Arial, Helvetica, sans-serif;
}

fieldset { 
  margin-top: 1.5em; 
  padding-bottom: 1em;
  border:1px solid #000000; 
  background-color: #eeeeee;
}

legend {
  font-weight: bold; 
  margin-left: 1em;
}

fieldset ol {
  list-style: none; 
  padding: 1em 1em 0 1em;
}

fieldset li {
  padding-bottom: .5em
}

fieldset p {
  margin: 1em 0 1em;
}

label {
  display: block; 
  line-height: 1.8em;
  vertical-align:top;
}

<!--[if lte IE 7]>
legend {
  position: relative; 
  top: -0.5em; z-index: 0;
}

fieldset {
  position: relative;
}
<![endif]-->
</style>
</head>
<body>
<h1>Contact Form Demo</h1>

<?php
if(isset($hasError)) { ?>
	<p class="error">Please check if you've filled all the fields with valid information. Thank you.</p>
<?php } ?>

<?php
if(isset($emailSent) && $emailSent == true) { ?>
	<p><strong>Email Successfully Sent!</strong></p>
	<p>Thank you <strong><?php echo $name;?></strong> for using my contact form! Your email was successfully sent and I will be in touch with you soon.</p>
<?php } else { ?>
	<form method="POST" action="<?php echo $_SERVER['PHP_SELF']; ?>" id="contactform">
	<fieldset>
	<legend>Contact Form</legend>
	<ol>
	<li><label for="Email">Email: </label><input id="id_email" type="text" name="email"/></li>
	<li><label for="Name">Name: </label><input id="id_name" type="text" name="name"/></li>
	<li><label for="Subject">Subject: </label><input id="id_subject" type="text" name="subject"/></li>
	<li><label for="Message">Message:</label><textarea id="id_message" rows="10" cols="40" name="message"></textarea></li>
	</ol>
	</fieldset>
	<p><input type="submit" class="button" id="id_submit" name="submit" value="Send Message" /></p>
	</form>
<?php } ?>
</body>
</html>

Some Next Steps

There are some possibilities for improving this contact form slightly. For one thing, the error message is not terribly helpful. You could add text to the $hasError variable that is more descriptive and then output the text of $hasError to help provide more useful feedback to the user. You can also add value attributes to the various form elements and echo the variables from the form into them. This way when the user does make an error, they are presented with a form with their previously entered data still filled in.

I hope this tutorial helped to point you in the right direction for building a usable and simple contact form in PHP. While this tutorial built a very basic contact form, it is easy to modify this contact form to provide better feedback to the end user.

Help us spread the word!
  • Twitter
  • Facebook
  • LinkedIn
  • Pinterest
  • Delicious
  • DZone
  • Reddit
  • Sphinn
  • StumbleUpon
  • Google Plus
  • RSS
  • Email
  • Print
If you liked this article, consider enrolling in one of these related courses:
Don't miss another post! Receive updates via email!

3 comments

  1. shafi says:

    time to change eregi()
    try soime thing like this

    if (preg_match(‘/^(‘ . $value . ‘)(;q=[0-9]\\.[0-9])?$/i’, $this->browser_languages[$i]) && isset($this->catalog_languages[$key])) {
    $this->language = $this->catalog_languages[$key];

  2. slim says:

    tu change !eregi par strpos

    if (!strpos(“^[A-Z0-9._%-]+@[A-Z0-9._%-]+\.[A-Z]{2,4}$”,trim($_POST[’email’]))) {
    $hasError = true;

  3. Awais Kamran says:

    I am really thankful to you…. Your PHP Form article just resolved my biggest problem, now I can submit my assignment on time. Thank you sooooo much!

Comment