Learn it fast with expert-taught software and skills training at lynda.com. See what you can learn

By David Powers | Saturday, July 19, 2014

Send Email from a Web Form with PHP

Use PHP to send the contents of a web form via email

Sending the contents of an online form to an email address is one of the most useful applications of PHP. It’s not difficult; but it’s easy to make a mistake. In this article, I’ll show you how to avoid common pitfalls that arise when sending the contents of a form with PHP.

Getting started

I assume you have a website that supports PHP. Although you can test part of the script locally, it’s simpler to test sending an actual email on a live website.

To keep things simple, I’m going to use a form with just three input fields and a submit button. The HTML looks like this:

<form method="post" action="acknowledge.php">

  <label for="name">Name:</label>
  <input type="text" name="name" id="name">


  <label for="email">Email:</label>
  <input type="email" name="email" id="email">


  <label for="comments">Comments:</label>
  <textarea name="comments" id="comments"></textarea>


  <input type="submit" name="send" value="Send Message">

</form>

The opening <form> tag contains two attributes: method and action. The method attribute tells the browser how to handle the data when the form is submitted. Always set it to post for email. Setting the form contents to the URL, which looks bad and risks exposing sensitive information. The action attribute tells the browser where to send the form data for processing. In this example, I’m sending it to a page called acknowledge.php.

The script that processes the form uses the name attribute of each input element to extract the data. Never use spaces in the name attribute. If you want to use multiple words, use camel case, such as productName, or an underscore (product_name).

Creating the page for the processing script

As well as processing the form data, the script will confirm whether the message has been sent. Create a web page with the following HTML in the <body> section, and save it as acknowledge.php in the same folder as the form:

<h1>Thank You</h1>
<p>Your message has been sent.</p>
<h1>Oops!</h1>
<p>Sorry, there was a problem sending your message.</p>

The page will eventually use PHP logic to display the correct message.

Gathering the data from the form

To access the data from a field, just add its name attribute in quotes in a pair of square brackets after $_POST. For example, $_POST['email'] contains the value of the field named email.

To process the form, you need to check that it has been submitted, and then build the content of the email message.

  1. Above the doctype in acknowledge.php, create a PHP code block like this:
<?php
if (isset($_POST['send'])) {
    
}
?>

The name of the submit button in my form is send, so this confirms that $_POST['send'] exists—in other words, the form has been submitted. If you use a different name for the submit button, change it to match. PHP variables are case-sensitive: $_post or $_Post won’t work. Also check that opening and closing parentheses match (there are two closing parentheses before the opening curly brace).

All the remaining code in this section goes between the curly braces, and will be executed only if the form has been submitted.

  1. Create two variables for the address where the email will be sent and the subject of the email:
if (isset($_POST['send'])) {
     $to = 'david@example.com'; // Use your own email address
     $subject = 'Feedback from my site';
}
  1. Start building the body of the email message on the next line:
$message = 'Name: ' . $_POST['name'] . "\r\n\r\n";

PHP uses a dot (period) to join strings (text) together, so this adds the value of the name field to the literal text ‘Name: ‘. The line finishes with two carriage returns and newline characters. Note that the \r\n\r\n is in double quotes. If you use single quotes, you’ll get \r\n\r\n as literal text.

  1. The body of the email message must be a single string, so add the remaining fields by preceding the equals sign with a dot like this:
$message .= 'Email: ' . $_POST['email'] . "\r\n\r\n";
$message .= 'Comments: ' . $_POST['comments'];

You don’t need the carriage returns and newline characters after the last field.

  1. Test your code so far by adding the following line to display the body of the message:
echo $message;
  1. Load the page with the form in a browser, type something in each field, and click the Send Message button. If everything goes well, you should see something similar to the following screenshot:

Success!

Figure 1: The contents of all form fields have been joined into a single string.

The carriage returns and newline characters are not displayed, but you can check their existence by viewing the source code in your browser.

Sending the email

Assuming all went well, you can try sending the email. PHP doesn’t send the mail. It acts as a go-between for the web server’s mail transport agent (MTA), so it’s best to do this on a live website.

  1. Delete echo $message; and replace it with the following code:
$success = mail($to, $subject, $message);

This passes three arguments to the mail() function: the address the email is being sent to, the subject line, and the <body> of the message. If the function succeeds in passing the message to the MTA, $success will be true.

  1. Edit the body section of the page like this to display the appropriate message:
<body>
<?php if (isset($success) && $success) { ?>
<h1>Thank You</h1>
Your message has been sent.
<?php } else { ?>
<h1>Oops!</h1>
Sorry, there was a problem sending your message.
<?php } ?>
</body>

If $success has been set, and if it’s true, the “Thank You” message is displayed. Otherwise, the error message is displayed. The error message will also be displayed if someone tries to reach acknowledge.php without submitting the form.

  1. Upload both the form and acknowledge.php to your website, and test the form again. If you get the “Thank You” message, check your mail inbox (and spam trap) to see if you get an email. If you do, congratulations. If not, don’t worry. The code so far is the absolute minimum for sending an email, and it doesn’t work on all servers.

Adding email headers

Even if you received an email from the existing script, you’ll almost certainly want to improve it by adding email headers. One of the most useful headers makes it easy to reply directly to the sender. But you need to do it correctly to avoid turning your online form into a spam relay.

  1. Insert a new line in the script just before the line that sends the email, and create a header for the From address like this:
$headers = "From: webmaster@example.com\r\n";

I’ve used double quotes because each header needs to be separated by a carriage return and newline character. Don’t put the sender’s email address in the From header. This header should be an address that uses your website’s domain name.

  1. Most websites these days use UTF-8 encoding. So add a new header on the next line using the dot-equals operator:
$headers .= 'Content-Type: text/plain; charset=utf-8';

I haven’t added a carriage return and newline character because the final header will be added only if the sender’s email address is valid.

  1. Malicious attackers try to exploit the email field of online forms to inject dozens of email addresses and spam content, so you need to validate the sender’s email address before adding it to the headers:
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
if ($email) {
   $headers .= "\r\nReply-To: $email";
}

The filter_input() function takes three arguments. The first one specifies that the input has been sent by the post method. The second is the name of the input field. The third argument specifies how to check the input. In this case, it validates that it’s a single email address. The first and third arguments are PHP constants, and are case-sensitive.

If the input doesn’t look like a valid email address, the function returns false. Otherwise, it returns the address, which is stored as $email. The Reply-To header is added only if the email looks OK. Putting the carriage return and newline character at the beginning has the same effect as adding it at the end of the previous header.

  1. Now that you’ve defined the additional email headers, pass them as the fourth argument to the mail() function:
$success = mail($to, $subject, $message, $headers);
  1. Save acknowledge.php, upload the revised version to your website, and test the form again. If you still don’t receive an email, check the next section.

Verifying that the email is from a trusted source

Many hosting companies require passing a fifth argument to mail() to verify that it comes from a trusted source. This is your own email address in quotes and preceded by -f (hyphen-f). If you still don’t get an email after adding the additional headers, change the line that sends the mail like this (using your own email address in the final argument):

$success = mail($to, $subject, $message, $headers, '‑fdavid@example.com');

Learning more about email and PHP

In this article, I’ve shown you how to create a basic PHP script to send input from an online form to an email address, and how to embed the sender’s email in the email headers without turning your form into a spam relay. You can also watch me describe each step in this free video.

There’s a lot more you can do to improve the user experience, such as checking errors, and handling different types of form input, including radio buttons and select menus. I go through all of these issues in detail in my Introducing PHP course on lynda.com. Also check out Ray Villalobos’s course Validating and Processing Forms with JavaScript and PHP.

Learn it from the experts.

With online video courses at lynda.com, you can reach your goals faster. Learn software, improve your skills, and get an inside look at how the professionals work.

See what you can learn


Share this article:

Tags: , , , ,

Get the latest news

  •   New course releases
  •   Pro tips and tricks
  •   News and updates
  
New releases submit clicked

You can change your email preferences at any time. We will never sell your email. More info

Featured articles

A lynda.com membership includes:

Unlimited access to thousands of courses in our library
Certificates of completion
New courses added every week (almost every day!)
Course history to track your progress
Downloadable practice files
Playlists and bookmarks to organize your learning
Become a member

Thanks for signing up.

We’ll send you a confirmation email shortly.


Sign up and receive emails about lynda.com and our online training library:

Here’s our privacy policy with more details about how we handle your information.

Keep up with news, tips, and latest courses with emails from lynda.com.

Sign up and receive emails about lynda.com and our online training library:

Here’s our privacy policy with more details about how we handle your information.

   
submit Lightbox submit clicked
Terms and conditions of use

We've updated our terms and conditions (now called terms of service).Go
Review and accept our updated terms of service.