PHP – Send Attachment with PHP mail()

Update @ 2014-03-10: If the following piece of code doesn’t work, you could try the comment written by karmaprod.

Update @ 2014-01-17: You may need to change the PHP_EOL setting in Windows environment as suggested by Rene.

By default, the PHP mail() does not support sending email with attachment. In order to send an attachment, u can either use the PEAR package or PHPMailer. But in reality, the hosting server may not provide these kinds of third party libraries.

A workaround for sending attachment using PHP mail() is to construct a MIME header which contains the attachment information. The following piece of codes should help.

<?php
/* Email Detials */
  $mail_to = "<receipient address>";
  $from_mail = "<sender address>";
  $from_name = "<sender name>";
  $reply_to = "<reply-to address>";
  $subject = "<email subject>";
  $message = "<email content>";

/* Attachment File */
  // Attachment location
  $file_name = "<attachment file name>";
  $path = "<relative path/absolute path which contains the attachment>";
  
  // Read the file content
  $file = $path.$file_name;
  $file_size = filesize($file);
  $handle = fopen($file, "r");
  $content = fread($handle, $file_size);
  fclose($handle);
  $content = chunk_split(base64_encode($content));
  
/* Set the email header */
  // Generate a boundary
  $boundary = md5(uniqid(time()));
  
  // Email header
  $header = "From: ".$from_name." <".$from_mail.">\r\n";
  $header .= "Reply-To: ".$reply_to."\r\n";
  $header .= "MIME-Version: 1.0\r\n";
  
  // Multipart wraps the Email Content and Attachment
  $header .= "Content-Type: multipart/mixed; boundary=\"".$boundary."\"\r\n";
  $header .= "This is a multi-part message in MIME format.\r\n";
  $header .= "--".$boundary."\r\n";
  
  // Email content
  // Content-type can be text/plain or text/html
  $header .= "Content-type:text/plain; charset=iso-8859-1\r\n";
  $header .= "Content-Transfer-Encoding: 7bit\r\n\r\n";
  $header .= "$message\r\n";
  $header .= "--".$boundary."\r\n";
  
  // Attachment
  // Edit content type for different file extensions
  $header .= "Content-Type: application/xml; name=\"".$file_name."\"\r\n";
  $header .= "Content-Transfer-Encoding: base64\r\n";
  $header .= "Content-Disposition: attachment; filename=\"".$file_name."\"\r\n\r\n";
  $header .= $content."\r\n";
  $header .= "--".$boundary."--";
  
  // Send email
  if (mail($mail_to, $subject, "", $header)) {
    echo "Sent";
  } else {
    echo "Error";
  }
?>

It should be able to deliver emails to Gmail and Hotmail without regarding as SPAM.

Done =)

About these ads

33 thoughts on “PHP – Send Attachment with PHP mail()

  1. Pingback: Configure Postfix/Sendmail for PHP mail() in Ubuntu | Eureka!

  2. Jitendra Purohit

    Fantastic Article… I really searched a lot and also tried a lot of codes but they just were not working. I needed to send an image as an attachment with an email to the member of the website. Real good effort there!!!

    Reply
  3. sumesh

    my wrapping makes a problem with this code it shows only the empty attachments file and no content in the body of the mail

    Reply
  4. Molik Jain

    its not working with me, don’t know why?
    showing error.
    what to do?

    but when I use sendmail on terminal, it dispatches email and takes to spam

    also in php.ini the path to sendmail is already given correctly on my linux machine

    mail with attachment will be a good thing, but for now I want the simple mails to work in php without attachments and then I am sure mails without attachments will also go out.

    can you help me please

    Reply
    1. ykyuen Post author

      Hi Molik,

      First of all, what error did you get? can you post it here?

      Second, if you find that the outgoing emails were treated as SPAM. most likely the domain is not in the email whitelist. Actually setup an email server is quite complicated and i dun have much experience on that. If you dun mind using gmail as a relay, i would suggest you read the following post.
      Postfix – Relay via Gmail

      I dun know if your server is using Sendmail/Postfix. In my experience, Postfix is more user friendly.

      Hope the above information could help.

      Kit

      Reply
  5. karmaprod

    I couldn’t have it working until I changed all those “$header” to “$message”. Here it is my working code:

    <?php
    // http://eureka.ykyuen.info/2010/02/16/php-send-attachmemt-with-php-mail/
    /* Email Detials */
    	$mail_to = "";
    	$from_mail = "";
    	$from_name = "";
    	$reply_to = "";
    	$subject = "";
    	$message = "";
    
    /* Attachment File */
    	// Attachment location
    	$file_name = "";
    	$path = "";
    	
    	// Read the file content
    	$file = $path.$file_name;
    	$file_size = filesize($file);
    	$handle = fopen($file, "r");
    	$content = fread($handle, $file_size);
    	fclose($handle);
    	$content = chunk_split(base64_encode($content));
    	
    /* Set the email header */
    	// Generate a boundary
    	$boundary = md5(uniqid(time()));
    	
    	// Email header
    	$header = "From: ".$from_name." \r\n";
    	$header .= "Reply-To: ".$reply_to."\r\n";
    	$header .= "MIME-Version: 1.0\r\n";
    	
    	// Multipart wraps the Email Content and Attachment
    	$header .= "Content-Type: multipart/mixed;\r\n";
    	$header .= " boundary=\"".$boundary."\"";
    
    	$message .= "This is a multi-part message in MIME format.\r\n\r\n";
    	$message .= "--".$boundary."\r\n";
    	
    	// Email content
    	// Content-type can be text/plain or text/html
    	$message .= "Content-Type: text/plain; charset=\"iso-8859-1\"\r\n";
    	$message .= "Content-Transfer-Encoding: 7bit\r\n";
    	$message .= "\r\n";
    	$message .= "$message_body\r\n";
    	$message .= "--".$boundary."\r\n";
    	
    	// Attachment
    	// Edit content type for different file extensions
    	$message .= "Content-Type: application/xml;\r\n";
    	$message .= " name=\"".$file_name."\"\r\n";
    	$message .= "Content-Transfer-Encoding: base64\r\n";
    	$message .= "Content-Disposition: attachment;\r\n";
    	$message .= " filename=\"".$file_name."\"\r\n";
    	$message .= "\r\n".$content."\r\n";
    	$message .= "--".$boundary."--\r\n";
    	
    	// Send email
    	if (mail($mail_to, $subject, $message, $header)) {
    		echo "Sent";
    	} else {
    		echo "Error";
    	}
    ?>
    
    Reply
  6. jasonre

    Will this work on a windows server running php?
    I am trying to use the above code and although I get sent displayed on the screen no email is received and I am not sure what to try?

    Reply
  7. Rene

    Thank you for this script, it’s helps me to find a error on mine.
    I also replace the \r\n by PHP_EOL and it’s working on my windows test enviroment and also on the linux server.

    Reply
  8. Daniel

    I was wondering if you could tell me how to use this script, i want to send an image, for where ” ” they are can you fill the blanks in with examples, also I’m trying to upload images only can you help me ?

    Reply
    1. ykyuen Post author

      just host the php file one a webserver which could run PHP and then fill in all details like <receipient address>

      Open this php file on the browser with http protocol and it should work.

      Reply
    1. ykyuen Post author

      i hvn’t tried that before but i guess you can repeat the following part to send more attachments.

        // Attachment
        // Edit content type for different file extensions
        $header .= "Content-Type: application/xml; name=\"".$file_name."\"\r\n";
        $header .= "Content-Transfer-Encoding: base64\r\n";
        $header .= "Content-Disposition: attachment; filename=\"".$file_name."\"\r\n\r\n";
        $header .= $content."\r\n";
        $header .= "--".$boundary."--";
      

       

      And the following article should be able to help too.
      How to send HTML emails with multiple attachments in PHP

      Reply
  9. Hemant

    sorry i forget to post my code here is my code

    /* Email Detials */
    $mail_to = "";
    $from_mail = "hemant.kumar@anaadihsoftech.in";
    $from_name = "Hemant";
    $reply_to = "";
    $subject = $name." want to customize his tshirt";
    $message = "Dear Admin below is customer deatils want to design his/her t-shirt,
      dlfkjasfldja;ldkjf;lakjsdflk;jakld;fjadfsdf
      From:- anurag
      Mobile:-7799833121
      Email id:-dfsj@jglk.com";
         
    /* Attachment File */
    // Attachment location
    $file_name = "image";
    $path = "";
     
    // Read the file content
    $file = $newname;
    $file_size = filesize($file);
    $handle = fopen($file, "r");
    $content = fread($handle, $file_size);
    fclose($handle);
    $content = chunk_split(base64_encode($content));
     
    /* Set the email header */
    // Generate a boundary
    $boundary = md5(uniqid(time()));
     
    // Email header
         
    
    
    $header = "MIME-Version: 1.0\r\n";
     
    // Multipart wraps the Email Content and Attachment
    $header .= "Content-Type: multipart/mixed; boundary=\"".$boundary."\"\r\n";
    $header .= "This is a multi-part message in MIME format.\r\n";
    $header .= "--".$boundary."\r\n";
     
    // Email content
    // Content-type can be text/plain or text/html
    $header .= "Content-type:text/plain; charset=iso-8859-1\r\n";
    $header .= "Content-Transfer-Encoding: 7bit\r\n\r\n";
    $header .= "$message\r\n";
    $header .= "--".$boundary."\r\n";
     
    //Email from and reply define 
    $header = "From: ".$from_name." \r\n";
    $header .= "Reply-To: ".$reply_to."\r\n"; 
     
     
    // Attachment
    // Edit content type for different file extensions
    $header .= "Content-Type: application/xml; name=\"".$file_name."\"\r\n";
    $header .= "Content-Transfer-Encoding: base64\r\n";
    $header .= "Content-Disposition: attachment; filename=\"".$file_name."\"\r\n\r\n";
    $header .= $content."\r\n";
    $header .= "--".$boundary."--";
     
    // Send email
    if (mail($mail_to, $subject,"", $header)) {
      echo "Sent";
    } else {
      echo "Error";
    }
    
    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s