Send mail via PHP and AJAX

This tutorial will show you how to send mail with user contact information using AJAX for feedback

Sending email through contact form using PHP is easy since PHP have built in mail() function.

1. Creating simple contact HTML form

First let’s create a simple contact form.


<html>
<body>
  <div>
    <form>
      <div>
        <label for="email">Email</label>
        <input id="emailInput" type="email" placeholder="Enter your email" name="email" required />
      </div>
      <div>
        <label for="subject">Subject</label>
        <input id="subjectInput" type="text" placeholder="Enter subject" name="subject" accept-charset="utf-8" required />
      </div>
      <div class="form-group">
        <label for="poruka">Message</label>
        <textarea id="msgInput" type="text" placeholder="Enter message" rows="5" name="msg" accept-charset="utf-8" required></textarea>
      </div>
    </form>
    <div>
      <button id="submitBtn" type="button" onclick="sendMail()">Send</button>
    </div>
    <div id="ajaxResponseSuccess" role="alert"> </div>
    <div id="ajaxResponseFail" role="alert"></div>
  </div>
  <script src="mailJS.js"></script>
</body>
</html>

Save this as contactForm.html

2. Creating JavaScript file for managing AJAX

We want to inform our user if the mail has been sent or not, and to notify him that he has to input all required data before sending e-mail.

Create function sendMail() in new JS file. I’m calling it mailJS.js. Don’t forget to import it on bottom of body in HTML file:

<script src="mailJS.js"><script>

First, we want to check if user inputted all required data. If user didn’t input all required data we want to inform it to do so.


function sendMail() {
  var email = document.getElementById("emailInput").value;
  var subject = document.getElementById("subjectInput").value;
  var msg = document.getElementById("msgInput").value;

  var errorMsg = "Please enter all information.";

  if (email == "" || subject == "" || msg == "") {
    document.getElementById("ajaxResponseFail").style.display = "block";
    document.getElementById("ajaxResponseFail").innerHTML = errorMsg;
  } else {

    var successMsg = "Mail sent. You will get confirmation soon.";
    var failMsg = "Mail not sent. Please try again.";
    //... sendMail() function
    //...
    //...
  }

After we informed user that he didn’t input all required data we want hide the information block again when user clicks on input field(s) to input missing data. We are using focus eventListener to do so.


//Paste this code snippet outside and before of sendMail() function
document.getElementById("emailInput").addEventListener("focus", function() {
  document.getElementById("ajaxResponseFail").style.display = "none";
  document.getElementById("ajaxResponseSuccess").style.display = "none";
})
document.getElementById("subjectInput").addEventListener("focus", function() {
  document.getElementById("ajaxResponseFail").style.display = "none";
  document.getElementById("ajaxResponseSuccess").style.display = "none";
})
document.getElementById("msgInput").addEventListener("focus", function() {
  document.getElementById("ajaxResponseFail").style.display = "none";
  document.getElementById("ajaxResponseSuccess").style.display = "none";
})

Since we are using AJAX we can’t use browser’s submit() function to call PHP script and send data. We must create new FormData() object in our JS function and append it with users input.


//...
//...
//...sendMail() function
var formdata = new FormData();
formdata.append("email", email);
formdata.append("subject", subject);
formdata.append("msg", msg);
//...sendMail() function
//...
//...

In formdata.append() function, first parameter is the name of data you are sending. It’s the name you have to use in PHP $_POST function to assign receiving value to variable.
Second parameter is the value parameter. You are going to write JS variable for each input field.

After we created FormData() object we can create new AJAX Request to send data to server.


//...
//...
//... sendMail() function
var xhttp;
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
  if (this.readyState == 4 && this.status == 200) {
    document.getElementById("ajaxResponseFail").style.display = "none";
    document.getElementById("ajaxResponseSuccess").style.display = "block";
    document.getElementById("ajaxResponseSuccess").innerHTML = successMsg;
  } else if (this.readyState == 4 && this.status != 200) {
    document.getElementById("ajaxResponseSuccess").style.display = "none";
    document.getElementById("ajaxResponseFail").style.display = "block";
    document.getElementById("ajaxResponseFail").innerHTML = failMsg;
  }
}
xhttp.open("POST", "sendMail.php", true);
xhttp.send(formdata);
}

AJAX is formed in XMLHttpRequest() object. 
xhttp.onreadystatechange calls a function when .readyState property changes. 
There are 5 states: 
0: request not initialized 
1: server connection established 
2: request received 
3: processing request 
4: request finished and response is ready 

You can inform users for every status change, but since we are sending small data, we want to inform the user when the request has finished, so we use state 4. 

Status 200 states that request has been processed successfully. 

xhttp.open() function opens connection to server. 
In xhttp.open() function, first parameter indicates transfer method. We are using POST method. 
Second parameter is location of PHP file we are calling. 
Third parameter is Boolean value if we are using asynchronous or synchronous transfer. It’s recommended to use async transfer, so that page doesn’t freeze while data is being transferred. 

xhttp.send() function sends data in its attribute.

3. Creating PHP file with mail() function

PHP mail() function accepts 5 attributes: 
1. TO – recipient of mail 
2. SUBJECT – Mail subject 
3. MESSAGE – Mail body 
4. HEADERS – Mix of additional mail headers: FROM, CC, BCC 
5. PARAMETERS – Additional parameters for additional mail configuration. We are not using parameters in this tutorial 

Since we have 3 inputs in our simple contact form, we need 3 variables to save written data.


<?php
 $subject = $_POST['subject'];
 $email = $_POST['email'];
 $msg = $_POST['msg'];
 //...sendMail.php
 //...
 //..
?>

In $subject we are going to save data written in subject input of our contact form. 
In $email we are going to save data written in email input of our contact form. 
In $msg we are going to save data written in msg input in our contact form. 

Before proceeding to next step, we want to check again if input data arrived successfully. We are using empty() function to check if variables are empty. if(!empty($subject) || !empty($email) || !empty($msg)){

If variables aren’t empty we proceed to creating mail request.


//...
//...
//...sendmail.php
if(!empty($subject) || !empty($email) || !empty($msg)){
$to = '[email protected]';
$headers = 'From:' . $email;
//...sendmail.php if function
//...
//...

In $to you should write receiving email address. 
In $headers we are going to save data from $email, with ‘From:’ keyword for cleaner function call. 

While using contact form on my page, I encountered problem when user input his @yahoo email. Yahoo blocks all emails not sent from their servers stated that they have been sent from @yahoo. If you want to see more why, go to this Wikipedia article DMARC
To bypass this problem you can save users email address by putting it in your message body, like this:


$msg = $_POST['msg'] . "\nFrom: " . $email;
$headers = 'From: My contact form';

To make sure PHP is going to use UTF-8 character encoding we are going to use mb_language() and mb_internal_encoding(“UTF-8”) functions. 
mb_language(“uni”) and mb_internal_encoding(“UTF-8") converts input text in UTF-8 encoding. 
Since we used mb_language() and mb_internal_encoding() we need to use mb_send_mail() function to send mail


//...
//...
//...sendmail.php if function
mb_language("uni");
mb_internal_encoding("UTF-8");
mb_send_mail($to,$subject,$msg,$headers);
//...sendmail.php if function
//...
//...

mb_send_mail() function have the same parameters list as mail() function.
First parameter is receiving email address.
Second parameter is mail subject.
Third parameter is mails body, and fourth parameter are additional headers.

Nice touch to all this is sending confirmation email to users’ email address. We can do this by using the same mail() function.


//...
//...
//...sendmail.php if function
 $respondMsg = 'message body.';
 $respondSubject = 'message subject';
 $respondHeaders = 'From: [email protected]';
          mb_send_mail($email,$respondSubject,$respondMsg,$respondHeaders);
}else {
  echo '403';
 }

Save this as sendMail.php

You can test HTML and JS file on your computer, but you will need to set local or remote web server to test PHP file.