PHP send mail with attachment

The era of new and enhanced technology has left some awesome impact on the technology world. One of them is the latest language PHP. This language has its own advantages in the website world.

Today I’m going to share another instance of this langauge, i.e sending email with PHP contact form with an attached file.

Since the script, I’m going to share here, is quite simple. So you will not have to spend your much time to learn this.


Download This Code

How to send mail with attachemnts in PHP ?

The answer is quite simple. Follow this script and you will be able to do it soon. So, just follow the steps to learn it quickly.

Required language

  • HTML
  • AJAX
  • PHP

The HTML file should like this

<div class="form-style" id="contact_form">
    <div class="form-style-heading" style="text-align:center; font-size: 22px;">Please fill &amp; Submit the form below</div>
    <div id="contact_results"></div>
    <div id="contact_body">
	    <span>Name <span class="required">*</span></span>
            <input type="text" name="name" id="name" required="true" class="input-field"/>
            <span>Email <span class="required">*</span></span>
            <input type="email" name="email" required="true" class="input-field"/>
	    <span>Contact Number <span class="required">*</span></span>
            <input type="text" name="phone2" maxlength="15"  required="true" class="tel-number-field long" />
            <input type="file" name="file_attach" class="input-field"/>
        <label for="field5">
	    <span>Additional Message <span class="required">*</span></span>
            <textarea name="message" id="message" class="textarea-field" required="true" placeholder="Write your message here"></textarea>
            <span>&nbsp;</span><input type="submit" id="submit_btn" value="Submit" />

There should be an AJAX request, which will gather the data from html form and send it to PHP mailer. You can write this AJAX script in the head section in html file or it can be called from external resources also. This file should look like this.

<script src=""></script>
<script type="text/javascript">
$(document).ready(function() {
    $("#submit_btn").click(function() { 
	    var proceed = true;
        //simple validation at client's end
        //loop through each field and we simply change border color to red for invalid fields		
		$("#contact_form input[required=true], #contact_form textarea[required=true]").each(function(){
			if(!$.trim($(this).val())){ //if this field is empty 
				$(this).css('border-color','red'); //change border color to red   
				proceed = false; //set do not proceed flag
			//check invalid email
			var email_reg = /^([w-.]+@([w-]+.)+[w-]{2,4})?$/; 
			if($(this).attr("type")=="email" && !email_reg.test($.trim($(this).val()))){
				$(this).css('border-color','red'); //change border color to red   
				proceed = false; //set do not proceed flag				
        if(proceed) //everything looks good! proceed...
           //data to be sent to server         
            var m_data = new FormData();    
            m_data.append( 'user_name', $('input[name=name]').val());
            m_data.append( 'user_email', $('input[name=email]').val());
            m_data.append( 'country_code', $('input[name=phone1]').val());
            m_data.append( 'phone_number', $('input[name=phone2]').val());
            m_data.append( 'subject', $('select[name=subject]').val());
			m_data.append( 'msg', $('textarea[name=message]').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: 'send.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>';
				$("#contact_form #contact_results").hide().html(output).slideDown();

    //reset previously set border colors and hide all message on .keyup()
    $("#contact_form  input[required=true], #contact_form textarea[required=true]").keyup(function() { 

We have included an external library file, i.e is necessary for the AJAX script to work

Now at last, there should a PHP file, which can send the stored data to the desired email. The PHP file should look like this

    $to_email       = ""; //Recipient email, Replace with own email here

    //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().
    $user_name      = filter_var($_POST["user_name"], FILTER_SANITIZE_STRING);
    $user_email     = filter_var($_POST["user_email"], FILTER_SANITIZE_EMAIL);
    $phone_number   = filter_var($_POST["phone_number"], FILTER_SANITIZE_NUMBER_INT);
    $subject        = "New Client for PSD Conversion";
    $message        = filter_var($_POST["msg"], FILTER_SANITIZE_STRING);
    //additional php validation
    if(strlen($user_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!'));
    if(!filter_var($user_email, FILTER_VALIDATE_EMAIL)){ //email validation
        $output = json_encode(array('type'=>'error', 'text' => 'Please enter a valid email!'));

    if(!filter_var($phone_number, FILTER_SANITIZE_NUMBER_FLOAT)){ //check for valid numbers in phone number field
        $output = json_encode(array('type'=>'error', 'text' => 'Enter only digits in phone number'));
    if(strlen($subject)<3){ //check emtpy subject
        $output = json_encode(array('type'=>'error', 'text' => 'Subject is required'));
    if(strlen($message)<3){ //check emtpy message
        $output = json_encode(array('type'=>'error', 'text' => 'Too short message! Please enter something.'));
    //email body
    $message_body = $message."rnrn".$user_name."rnEmail : ".$user_email."rnPhone Number : (".$country_code.") ". $phone_number ;

	### Attachment Preparation ###
	$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
		# Mail headers should work with most clients
		$headers = "MIME-Version: 1.0rn";
		$headers = "X-Mailer: PHP/" . phpversion()."rn";
		$headers .= "From: ".$user_email."rn";
		$headers .= "Subject: ".$subject."rn";
		$headers .= "Reply-To: ".$user_email."" . "rn";
		$headers .= "Content-Type: multipart/mixed; boundary=".md5('boundary1')."rnrn";
		$headers .= "--".md5('boundary1')."rn";
		$headers .= "Content-Type: multipart/alternative;  boundary=".md5('boundary2')."rnrn";
		$headers .= "--".md5('boundary2')."rn";
		$headers .= "Content-Type: text/plain; charset=utf-8rnrn";
		$headers .= $message_body."rnrn";
		$headers .= "--".md5('boundary2')."--rn";
		$headers .= "--".md5('boundary1')."rn";
		$headers .= "Content-Type:  ".$file_type."; ";
		$headers .= "name="".$file_name.""rn";
		$headers .= "Content-Transfer-Encoding:base64rn";
		$headers .= "Content-Disposition:attachment; ";
		$headers .= "filename="".$file_name.""rn";
		$headers .= "X-Attachment-Id:".rand(1000,9000)."rnrn";
		$headers .= $encoded_content."rn";
		$headers .= "--".md5('boundary1')."--";
		//proceed with PHP email.
		$headers = 'From: '.$user_name.'' . "rn" .
		'Reply-To: '.$user_email.'' . "rn" .
		'X-Mailer: PHP/' . phpversion();
    $send_mail = mail($to_email, $subject, $message_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 '.$user_name .' Thank you for your order, will get back to you shortly'));

That’s all about the sending email in PHP with attachment. Although this process also requires some AJAX script, but this is the best example, which can be used for your contact form.

Social Link

Swapnil Raja

Swapnil Raja is a technophile. He writes on scripting language, designing software, web technology, CMS and other technology related stuff. He is aregular contributor on Want to know more about him ? feel free to get in touch with him on different social platform.
Social Link

Latest posts by Swapnil Raja (see all)

Author: Swapnil Raja

Swapnil Raja is a technophile. He writes on scripting language, designing software, web technology, CMS and other technology related stuff. He is a regular contributor on Want to know more about him ? feel free to get in touch with him on different social platform.