Sending emails with attachments using PHP’s mail() function
Author: willem In: coding, php, tips & tricks, web developmentUpdate 2009/11/19: Some readers emailed me to mention that the script below doesn’t always work properly on all platforms (email messages are sometimes received with attachments but no content, or are sometimes completely blank). If the script below doesn’t work for you, Geekology has another post that details a method of sending emails with attachments in a PHP script that makes use of an external library.
If you need to send an email with attachments using just PHP’s mail() function, you can do so by using a multipart/mixed content header and converting the attachments to base64 strings.
First, generate a random hash to serve as a MIME Boundary:
$random_hash = md5(date('r', time()));
Next, set some email headers:
$headers = "From: noreply@geekology.co.za\r\nReply-To: noreply@geekology.co.za"; $headers .= "\r\nContent-Type: multipart/mixed; boundary=\"PHP-mixed-".$random_hash."\"";
… then convert the attachment into a base64 string:
$attachment = chunk_split(base64_encode(file_get_contents("geekology.zip")));
Finally, define the content of the email similar to the example below, then send it using PHP’s mail() function:
<?php $to = "willem@geekology.co.za"; $subject = "A test email"; $random_hash = md5(date('r', time())); $headers = "From: noreply@geekology.co.za\r\nReply-To: noreply@geekology.co.za"; $headers .= "\r\nContent-Type: multipart/mixed; boundary=\"PHP-mixed-".$random_hash."\""; $attachment = chunk_split(base64_encode(file_get_contents("geekology.zip"))); $output = " --PHP-mixed-$random_hash; Content-Type: multipart/alternative; boundary='PHP-alt-$random_hash' --PHP-alt-$random_hash Content-Type: text/plain; charset='iso-8859-1' Content-Transfer-Encoding: 7bit Hello World! This is the simple text version of the email message. --PHP-alt-$random_hash Content-Type: text/html; charset='iso-8859-1' Content-Transfer-Encoding: 7bit <h2>Hello World!</h2> <p>This is the <b>HTML</b> version of the email message.</p> --PHP-alt-$random_hash-- --PHP-mixed-$random_hash Content-Type: application/zip; name=geekology.zip Content-Transfer-Encoding: base64 Content-Disposition: attachment $attachment --PHP-mixed-$random_hash--"; echo @mail($to, $subject, $output, $headers); ?>
Related posts:
- A simpler way to send Text or HTML emails with attachments in PHP
- Forcing a Return-Path header when sending email with PHP’s mail() function
- Testing SMTP servers from a UNIX command line
- Validating and sanitizing URLs, Emails, and other inputs with PHP’s filter_* functions
- Transfer your business emails to Google Apps with Google Email Uploader for Mac
Like this post? Subscribe to the Geekology RSS 2.0 feed!












XkiD | Sending emails with attachments using PHP’s mail() function | blog.xkid.ro
June 29th, 2009 at 10:16
[...] the rest here: Sending emails with attachments using PHP’s mail() function Posted in PHP | Tags: a-freelance-web, a-random-hash, assignments, attachments, boundary, [...]
Eric
July 17th, 2009 at 18:38
After scratching my head for a while I came across this and the attachment works. Only one I could find that deals with the attachment correctly, thanks. The only problem is that I cannot get the text or html version of the body to show up in the actual email. Any thoughts?
Thanks,
Eric
willem
July 19th, 2009 at 19:15
Hi Eric
The exact structure of the header contents (including the amount and position of linebreaks) are very important.
I assume it’s you that sent the test messages to me from the info@… address? In those messages, spaces were added before the raw header content lines. Could you please update your script to start with the initial linebreak after ‘$output = “‘ that I use above, not add any spaces before the raw lines following it, then send me a test again?
Thanks!
revathy
July 22nd, 2009 at 11:23
Hi there, I used the above code to send mail with attachment. Now i can able to receive a mail with attachment, but if i attach a text file, while try to open it after downloading from mail, it has no content. If i tried to open jpg file attachment then it shows “No Preview available”. I don’t know where i did mistake. If anyone know the solution, please help me for this issue.
Eric
July 23rd, 2009 at 18:26
Be sure you have the line spaces just as you see them in the code. They make the difference. If you condensed the code down to get rid of extra lines then it won’t work. The attachments will go through but will end up corrupt. So be sure to leave the spaces in as you see them.
Hope this helps.
revathy
July 24th, 2009 at 06:07
Thank you very much Eric. The code works now. Thanks a lot…
kaizer
July 27th, 2009 at 12:14
Hi
I have been trying your code since friday and the attachment works fine but the email dont display ant message body. I tried doing what you said about the exact header contents but still no luck please advice
Revathy
July 27th, 2009 at 13:39
Hai ,
Use this code in your php file.
Martin
July 29th, 2009 at 14:28
Hi Willem
You are probably inudated with questions about your script and thats because it’s the only script inexperienced webber like me can follow.
I do though have two questions:
1) The attachments is attached to the email OK, but the attachment file size is Zero, i.e. there is no content to the zip, even though my file Attach. zip is 125K
2) How can I send my text content using your example? I have a pretty large form that needs to be complete and I need to perform some logic before sending the data.
Using your excellent scrip, I have put together an example for you, your comments and guidence will be gratefully appreciated.
willem
July 29th, 2009 at 16:53
Hi Martin
The blog software is probably stripping out some characters from your example, could you please email the script file to me at willem@geekology.co.za and I’ll take a look?
mani kandan
August 5th, 2009 at 22:24
Im using your script. If file is already exists in a folder then your code is working fine.
If im generating the .zip files dynamically its not working.
May i know what is the reason
Eric
August 6th, 2009 at 14:47
If you are creating the file to be mailed it should work fine. Are you 100% sure the file has the correct name and the extension is the proper one? Also, are you sure the application type is correct? I do this now with databases. I have them created on the fly and send them out. It does not have a problem. Make sure the name of the file you are creating are set with a variable. Then use the variable where it is needed in the mail. My feeling is that you’re not getting the file in the email but are getting the email. If so then it is the naming.
Hope this makes sense,
Eric
ramesh
September 19th, 2009 at 10:10
Hi all,
I am new to php and i am trying to send email with pdf file as attachment,above code.Now i can able to receive a mail with attachment,but i got message as adobe reader
could not open file because it is either not supportted filetype or file has been damaged.
here i am pasting code.please help me.
$to = “ramesh.naga@honeywell.com”;
$subject = “A test email”;
$random_hash = md5(date(’r', time()));
$headers = “From: ramesh.naga@honeywell.com\r\nReply-To: noreply@geekology.co.za“;
$headers .= “\r\nContent-Type: multipart/mixed; boundary=\”PHP-mixed-”.$random_hash.”\”";
$attachment = chunk_split(base64_encode(file_get_contents(”ramesh.pdf”)));
$output = ”
–PHP-mixed-$random_hash;
Content-Type: multipart/alternative; boundary=’PHP-alt-$random_hash’
–PHP-alt-$random_hash
Content-Type: text/plain; charset=’iso-8859-1′
Content-Transfer-Encoding: 7bit
Hello World!
This is the simple text version of the email message.
–PHP-alt-$random_hash
Content-Type: text/html; charset=’iso-8859-1′
Content-Transfer-Encoding: 7bit
Hello World!
This is the HTML version of the email message.
–PHP-alt-$random_hash–
–PHP-mixed-$random_hash
Content-Type: application/pdf; name=ramesh.pdf
Content-Transfer-Encoding: base64
Content-Disposition: attachment
$attachment
–PHP-mixed-$random_hash–”;
echo @mail($to, $subject, $output, $headers);
?>
Dwayne
September 24th, 2009 at 20:18
After some frustration, I was able to get this working. Seems there were some issues with the boundaries as defined above. My code is as follows:
$to = ‘user@domain.com’;
$subject = ‘Test email message’;
$random_hash = md5(date(’r', time()));
$headers = “From: sender@domain.com\r\nReply-To: sender@domain.com\r\n”;
$headers .= “Content-Type: multipart/mixed; boundary=\”PHP-mixed-”.$random_hash.”\”";
$attachment = chunk_split(base64_encode(file_get_contents($pdfFilename)));
$output = ”
–PHP-mixed-$random_hash
Content-Type: text/plain; charset=’iso-8859-1′
This is the simple text version of the email message.
–PHP-mixed-$random_hash
Content-Type: text/html; charset=’iso-8859-1′
This is the simple text version of the email message.
–PHP-mixed-$random_hash
Content-Type: application/pdf; name=$pdfFilename
Content-Transfer-Encoding: base64
Content-Disposition: attachment
$attachment
–PHP-mixed-$random_hash–”;
if (@mail($to, $subject, $output, $headers)) {
echo ‘Mail sent’;
} else {
echo ‘Mail NOT sent’;
}
var_dump($headers, $output);
Richard
October 14th, 2009 at 15:51
I found a similar link at http://www.webcheatsheet.com/php/send_email_text_html_attachment.php.
I tried using the one you gave here which works perfectly till i open the attachment. Im not sure if directly copying and pasting code from a browser to my development software ( Dreamweaver CS3 ) adds any additional whitespace | extra characters.
Thanks for the help
jordan
November 3rd, 2009 at 03:24
hi there, first off thank you for the script. i have struggled with attaching files to emails using mail() for quite some time.
i’ve copied your script exactly, changing only the $to variable and the “From” section to contain my email addresses. i have not added/removed spacing or modified the structure.
i’m happy to report that i received the attachment and was able to read it, download it, etc. without error. the problem is that neither the plain text nor the html text shows up in the email. i read your response above about the spacing/structure having to match exactly but since i copied your script directly, have not modified its spacing/structure, and am receiving the attachments, i think there is something else wrong.
when i viewed the full headers (in gmail), the plain text and html text was included but it does not show up in the regular email. even a view source does not contain the text.
any help you could provide will be greatly appreciated. thank you!
Matt
November 4th, 2009 at 23:55
After days of frustration, I’ve finally found my answer.
Great post–Thanks a ton for the help!!!
infosekr
November 8th, 2009 at 09:51
I wasn’t able to get the body of the message to appear. After some trial and error i found the problem to be in the top of the message body in this posting.
$output = ”
–PHP-mixed-$random_hash;
Content-Type: multipart/alternative; boundary=’PHP-alt-$random_hash’
The boundary string is wrapped in single quotes. When i changed them to double quotes (/”) then my message body came through ok.
Medo
December 2nd, 2009 at 08:33
i have the same problem the html text body it doesnt show at alla any ideas
praveen
December 7th, 2009 at 16:08
Hi,
I want to send the pdf file as an attachment instead of zip file.
I changed the file name and apllication/pdf in ContentType.
I received the mail with an attachment but when I tried to open the attach pdf. It gives error.
“Adobe Reader could not open ‘filename.pdf’ because it is either not a supported file type or because the file has been damaged(for example, it was send as an email attachment and wasn’t correctly decoded).”
Any idea?
Thanks in advance.
R. Canser
January 29th, 2010 at 18:03
Hi.
When i post a message to my address via this script, i get dozens of paragraphs like this :
/9j/4AAQSkZJRgABAgEAYABgAAD/4RA2RXhpZgAATU0AKgAAAAgABwEyAAIAAAAUAAAAYkdGAAMA…
I tried too many times and i could not get it worked.
Please help…
willem
January 31st, 2010 at 10:23
@Canser: You might want to try my alternative suggestion, here:
http://www.geekology.co.za/blog/2009/11/simpler-way-to-send-text-html-emails-with-attachments-in-php/
Tilapic
February 11th, 2010 at 12:06
Hello R. Canser
I had the same problem with the attachment showing up as characters in the mail body.
Try to delete the “\r” in the headers it worked for me.
$headers = “From: $from\r\n” .
“MIME-Version: 1.0\r\n” .
“Content-Type: multipart/mixed;\r\n” .
” boundary=\”{$mime_boundary}\”";
Eric L.
February 26th, 2010 at 04:07
OMG Tilapic you made my day! I had the same problem as R. Canser and you trick works. I would never have tought of trying that… Do you know why we need to remove the “\r”??