Today, We are going to learn steps to send an email with attachment using PHP and Ajax without refreshing the page. Below is the step by step explanation.

Before we are getting started, we need a little bit of knowladge about HTML, CSS, PHP and jQuery.

  1. HTML form that will collect the Information from the user
  2. Ajax will gather all the data submitted by the form and send to process.php to send an email
  3. process.php will check the whether attachment is there or not and trigger a email.


Filename : index.html

This is the page where we have a simple form that collect all the information from the user to send email via PHP mail.

<form id="contact-form" method="post" enctype="multipart/form-data">
  <div class="form-group">
    <label for="fname">First Name:</label>
    <input type="text" class="form-control" id="fname">
  <div class="form-group">
    <label for="email">Email Address:</label>
    <input type="email" class="form-control" id="email_address">
  <div class="form-group">
  <label for="attachment">File attachment:</label>
   <input type="file" name="file_attach" class="input-field"/>
  <button type="button" id="submit" class="btn btn-default btn-dark">Submit</button>

Above form have fields like First Name, Email Address and File attachment. Each input filed has their unique ID to fetch the data once form has submitted.

Note : We have set  enctype=”multipart/form-data” . This is used for file attachment.

Script that gather all information submitted by the Form and pass the data to process.php to send email.

<script src=""></script>
<script type="text/javascript">
  $(document).ready(function() {
           $("#submit").click(function(e) {
               var proceed = true;

               if(proceed) //everything looks good! proceed...

           //data to be sent to server        
            var m_data = new FormData();   
            m_data.append( 'first_name', $('#fname').val());
            m_data.append( 'email_address', $('#email_address').val());
            m_data.append( 'file_attach', $('input[name=file_attach]')[0].files[0]);
            //instead of $.post() we are using $.ajax()
            //that's because $.ajax() has more options and flexibly.

              url: 'process.php',
              data: m_data,
              processData: false,
              contentType: false,
              type: 'POST',
              success: function(response){
                 //load json data from server and output message    
                if(response.type == 'error'){ //load json data from server and output message    
                    output = '<div class="error">'+response.text+'</div>';
                    output = '<div class="success">'+response.text+'</div>';






    //Recepient Email Address
    $to_email       = "";

    //check if its an ajax request, exit if not
    if(!isset($_SERVER['HTTP_X_REQUESTED_WITH']) AND strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) != 'xmlhttprequest') {
        $output = json_encode(array( //create JSON data
            'text' => 'Sorry Request must be Ajax POST'
        die($output); //exit script outputting json data

    //Sanitize input data using PHP filter_var().
    $first_name      = filter_var($_POST["first_name"], FILTER_SANITIZE_STRING);
    $email_address   = filter_var($_POST["email_address"], FILTER_SANITIZE_EMAIL);
    $subject         = "Your Email Subject Goes Here...";
    //Textbox Validation 
    if(strlen($first_name)<4){ // If length is less than 4 it will output JSON error.
        $output = json_encode(array('type'=>'error', 'text' => 'Name is too short or empty!'));

    $message = '<html><body>';
    $message .= '<table rules="all" style="border-color: #666;" cellpadding="10">';
    $message .= "<tr style='background: #eee;'><td><strong>First Name:</strong> </td><td>" . strip_tags($_POST['first_name']) . "</td></tr>";
    $message .= "<tr><td><strong>Email Address :</strong> </td><td>" . strip_tags($_POST['email_address']) . "</td></tr>";
    $message .= "</table>";
    $message .= "</body></html>";

    $file_attached = false;
    if(isset($_FILES['file_attach'])) //check uploaded file
        //get file details we need
        $file_tmp_name    = $_FILES['file_attach']['tmp_name'];
        $file_name        = $_FILES['file_attach']['name'];
        $file_size        = $_FILES['file_attach']['size'];
        $file_type        = $_FILES['file_attach']['type'];
        $file_error       = $_FILES['file_attach']['error'];

        //exit script and output error if we encounter any
            $mymsg = array(
            1=>"The uploaded file exceeds the upload_max_filesize directive in php.ini",
            2=>"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form",
            3=>"The uploaded file was only partially uploaded",
            4=>"No file was uploaded",
            6=>"Missing a temporary folder" );
            $output = json_encode(array('type'=>'error', 'text' => $mymsg[$file_error]));
        //read from the uploaded file & base64_encode content for the mail
        $handle = fopen($file_tmp_name, "r");
        $content = fread($handle, $file_size);
        $encoded_content = chunk_split(base64_encode($content));
        //now we know we have the file for attachment, set $file_attached to true
        $file_attached = true;


    if($file_attached) //continue if we have the file
    // a random hash will be necessary to send mixed content
    $separator = md5(time());

    // carriage return type (RFC)
    $eol = "\r\n";

    // main header (multipart mandatory)
    $headers = "From:Fromname <>" . $eol;
    $headers .= "MIME-Version: 1.0" . $eol;
    $headers .= "Content-Type: multipart/mixed; boundary=\"" . $separator . "\"" . $eol;
    $headers .= "Content-Transfer-Encoding: 7bit" . $eol;
    $headers .= "This is a MIME encoded message." . $eol;

    // message
    $body .= "--" . $separator . $eol;
    $body .= "Content-type:text/html; charset=utf-8\n";
    $body .= "Content-Transfer-Encoding: 7bit\r\n\r\n";
    $body .= $message . $eol;

    // attachment
    $body .= "--" . $separator . $eol;
    $body  .= "Content-Type:".$file_type." ";
    $body .= "Content-Type: application/octet-stream; name=\"" . $file_name . "\"" . $eol;
    $body .= "Content-Transfer-Encoding: base64" . $eol;
    $body .= "Content-Disposition: attachment; filename=\"".$file_name."\"". $eol;
    $body .= $encoded_content . $eol;
    $body .= "--" . $separator . "--";
        $eol = "\r\n";
        $headers = "From: Fromname <>" . $eol;
        $headers .= "Reply-To: ". strip_tags($email_address) . "\r\n";
        $headers .= "MIME-Version: 1.0\r\n";
        $headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n";
        $body .= $message . $eol;


    $send_mail = mail($to_email, $subject, $body, $headers);
        //If mail couldn't be sent output error. Check your PHP email configuration (if it ever happens)
        $output = json_encode(array('type'=>'error', 'text' => 'Could not send mail! Please check your PHP mail configuration.'));
        $output = json_encode(array('type'=>'message', 'text' => 'Hi '.$first_name .' Thank you for your order, will get back to you shortly'));



Demo | Download

14 thoughts on “Simple Ajax Form With Email Attachment Using PHP

  1. I do not even know how I ended up here, but I believed this submit used to be great. I don’t recognize who you might be but certainly you’re going to a well-known blogger should you are not already Cheers!

    1. Place below code above Line Number 80 . This will help you to upload only with extensions of PDF, DOC, DOCX files.

      $allowedExts = array( "pdf", "doc", "docx" );
      $extension = end(explode(".", $_FILES['file_attach']['name'] ));

      if ( ! ( in_array($extension, $allowedExts ) ) ) {
      $output = json_encode(array('type'=>'error', 'text' => 'Only PDF, DOC and DOCX extensions are allowed'));

  2. The demo is working fine but the download link is incorrect.

    After copying the script, I received the mail but the the attached file got corrupted.

    Please suggest.

  3. I simply want to mention I’m all new to blogs and certainly loved you’re website. Most likely I’m likely to bookmark your site . You definitely come with impressive articles. Thanks for revealing your website.

Leave a Reply

Your email address will not be published. Required fields are marked *