You can send emails very easily with PHP by the help of mail() function, but how does one send attachment attached to that email?
You’ll still use mail() function, but with a little more twists in the header argument — yes, the content of the attached file is actually encoded into the header of the email, can you believe that. Big head.
Unfortunately, it’s a pain in the ass every time you have to get through all the chores needed to attach and encode the file into the email header. You have to know the size of the file, base64_encode() it, chunk_split() it and set all the configurations required in the header so that the email client can recognize that something’s in the header and can extract it out as an attachment.
Anyway, I’ve made this class AttachmentEmail that you can email an attachment with PHP more easily. All the chores are taken care of. It’s written in a hurry so the structure can sure be better. Other than this, it works like a charm.
The Class:
class AttachmentEmail {
private $from = '[email protected]';
private $from_name = 'Your Name';
private $reply_to = '[email protected]';
private $to = '';
private $subject = '';
private $message = '';
private $attachment = '';
private $attachment_filename = '';
public function __construct($to, $subject, $message, $attachment = '', $attachment_filename = '') {
$this -> to = $to;
$this -> subject = $subject;
$this -> message = $message;
$this -> attachment = $attachment;
$this -> attachment_filename = $attachment_filename;
}
public function mail() {
if (!empty($this -> attachment)) {
$filename = empty($this -> attachment_filename) ? basename($this -> attachment) : $this -> attachment_filename ;
$path = dirname($this -> attachment);
$mailto = $this -> to;
$from_mail = $this -> from;
$from_name = $this -> from_name;
$replyto = $this -> reply_to;
$subject = $this -> subject;
$message = $this -> message;
$file = $path.'/'.$filename;
$file_size = filesize($file);
$handle = fopen($file, "r");
$content = fread($handle, $file_size);
fclose($handle);
$content = chunk_split(base64_encode($content));
$uid = md5(uniqid(time()));
$name = basename($file);
$header = "From: ".$from_name." <".$from_mail.">\r\n";
$header .= "Reply-To: ".$replyto."\r\n";
$header .= "MIME-Version: 1.0\r\n";
$header .= "Content-Type: multipart/mixed; boundary=\"".$uid."\"\r\n\r\n";
$header .= "This is a multi-part message in MIME format.\r\n";
$header .= "--".$uid."\r\n";
$header .= "Content-type:text/plain; charset=iso-8859-1\r\n";
$header .= "Content-Transfer-Encoding: 7bit\r\n\r\n";
$header .= $message."\r\n\r\n";
$header .= "--".$uid."\r\n";
$header .= "Content-Type: application/octet-stream; name=\"".$filename."\"\r\n"; // use diff. tyoes here
$header .= "Content-Transfer-Encoding: base64\r\n";
$header .= "Content-Disposition: attachment; filename=\"".$filename."\"\r\n\r\n";
$header .= $content."\r\n\r\n";
$header .= "--".$uid."--";
if (mail($mailto, $subject, "", $header)) {
return true;
} else {
return false;
}
} else {
$header = "From: ".($this -> from_name)." <".($this -> from).">\r\n";
$header .= "Reply-To: ".($this -> reply_to)."\r\n";
if (mail($this -> to, $this -> subject, $this -> message, $header)) {
return true;
} else {
return false;
}
}
}
}
The Usage:
For example, there’s this file residing on your web server at the path: /home/racker/gift.jpg and you want it attached to an email you are sending to Marry:
$sendit = new AttachmentEmail('[email protected]', 'Merry Christmas!', 'Hi', '/home/racker/gift.jpg');
$sendit -> mail();
The last argument ($attachment_filename) can be left empty if a filename is included in the second to last argument ($attachment). Otherwise you have to make clear what the file name is so the class can grab it and send it via attachment.
It returns true if the delivery is successful, otherwise false.
Pingback: A Basic PHP Contact Form Script
Nice little class, I like it
Glad to know! 🙂
Shouldn’t that be AttachmentMail instead of AttachmentEmail .. (E)
$sendit = new AttachmentMail(‘[email protected]’, ‘Merry Christmas!’, ‘Hi’, ‘/home/racker/gift.jpg’);
$sendit -> mail();
Thanks, got it fixed. 🙂
Just what I was looking for. Thanks dude!
This worked perfect, zip, pdf, whatever I need to e-mail! Thanks so much!
Glad it works for all of you!
Perfect! I took the liberty of modifying it to handle multiple attachments. Thanks!
Yeah, multiple attachments, that’d be a great idea for enhancement. Thanks!
many thanks for the class it is great
-> matt care to share how the multiple attachments mod? that would be great thanks
Old post, but I used this class on a project back in the days in a Drupal project. The customer now needed multiple attachments, so I updated the class with this functionality. Also added Phill’s mime types.
I put it up on Github: https://github.com/tommyeliassen/AttachmentEmail
Note that it uses Drupal file handling, but this should be easy to change back to normal PHP file handling.
Contact me if there are any questions.
Oops, disregard the Drupal file handling stuff, that was outside this class 🙂
Pingback: TemplateTweak :: Services
It’s nice that you all post this stuff, by why not include the full code with the post so that people that are new to this stuff would know where to put this code into the original script? This is totally worthless now. Why do you all think we are mind readers..!
I’m not sure what you mean by *original script* – perhaps you are lost in where to put these code in your own script?
I think any place would do, just make sure The Class part is before The Usage part. And when you run the script or when someone requests that script in browser address bar that contains The Usage part, it will send out the email containing the attachment.
thanks mate, it was making my life easy … I’m in such a rush at the end of my project so you’ve spared me some time…
cheers
This works great , Thank you
Adding a MIME Type function to your class and alter the header
public function getMimeType($file) {
// MIME types array
$mimeTypes = array(
"323" => "text/h323",
"acx" => "application/internet-property-stream",
"ai" => "application/postscript",
"aif" => "audio/x-aiff",
"aifc" => "audio/x-aiff",
"aiff" => "audio/x-aiff",
"asf" => "video/x-ms-asf",
"asr" => "video/x-ms-asf",
"asx" => "video/x-ms-asf",
"au" => "audio/basic",
"avi" => "video/x-msvideo",
"axs" => "application/olescript",
"bas" => "text/plain",
"bcpio" => "application/x-bcpio",
"bin" => "application/octet-stream",
"bmp" => "image/bmp",
"c" => "text/plain",
"cat" => "application/vnd.ms-pkiseccat",
"cdf" => "application/x-cdf",
"cer" => "application/x-x509-ca-cert",
"class" => "application/octet-stream",
"clp" => "application/x-msclip",
"cmx" => "image/x-cmx",
"cod" => "image/cis-cod",
"cpio" => "application/x-cpio",
"crd" => "application/x-mscardfile",
"crl" => "application/pkix-crl",
"crt" => "application/x-x509-ca-cert",
"csh" => "application/x-csh",
"css" => "text/css",
"dcr" => "application/x-director",
"der" => "application/x-x509-ca-cert",
"dir" => "application/x-director",
"dll" => "application/x-msdownload",
"dms" => "application/octet-stream",
"doc" => "application/msword",
"dot" => "application/msword",
"dvi" => "application/x-dvi",
"dxr" => "application/x-director",
"eps" => "application/postscript",
"etx" => "text/x-setext",
"evy" => "application/envoy",
"exe" => "application/octet-stream",
"fif" => "application/fractals",
"flr" => "x-world/x-vrml",
"gif" => "image/gif",
"gtar" => "application/x-gtar",
"gz" => "application/x-gzip",
"h" => "text/plain",
"hdf" => "application/x-hdf",
"hlp" => "application/winhlp",
"hqx" => "application/mac-binhex40",
"hta" => "application/hta",
"htc" => "text/x-component",
"htm" => "text/html",
"html" => "text/html",
"htt" => "text/webviewhtml",
"ico" => "image/x-icon",
"ief" => "image/ief",
"iii" => "application/x-iphone",
"ins" => "application/x-internet-signup",
"isp" => "application/x-internet-signup",
"jfif" => "image/pipeg",
"jpe" => "image/jpeg",
"jpeg" => "image/jpeg",
"jpg" => "image/jpeg",
"js" => "application/x-javascript",
"latex" => "application/x-latex",
"lha" => "application/octet-stream",
"lsf" => "video/x-la-asf",
"lsx" => "video/x-la-asf",
"lzh" => "application/octet-stream",
"m13" => "application/x-msmediaview",
"m14" => "application/x-msmediaview",
"m3u" => "audio/x-mpegurl",
"man" => "application/x-troff-man",
"mdb" => "application/x-msaccess",
"me" => "application/x-troff-me",
"mht" => "message/rfc822",
"mhtml" => "message/rfc822",
"mid" => "audio/mid",
"mny" => "application/x-msmoney",
"mov" => "video/quicktime",
"movie" => "video/x-sgi-movie",
"mp2" => "video/mpeg",
"mp3" => "audio/mpeg",
"mpa" => "video/mpeg",
"mpe" => "video/mpeg",
"mpeg" => "video/mpeg",
"mpg" => "video/mpeg",
"mpp" => "application/vnd.ms-project",
"mpv2" => "video/mpeg",
"ms" => "application/x-troff-ms",
"mvb" => "application/x-msmediaview",
"nws" => "message/rfc822",
"oda" => "application/oda",
"p10" => "application/pkcs10",
"p12" => "application/x-pkcs12",
"p7b" => "application/x-pkcs7-certificates",
"p7c" => "application/x-pkcs7-mime",
"p7m" => "application/x-pkcs7-mime",
"p7r" => "application/x-pkcs7-certreqresp",
"p7s" => "application/x-pkcs7-signature",
"pbm" => "image/x-portable-bitmap",
"pdf" => "application/pdf",
"pfx" => "application/x-pkcs12",
"pgm" => "image/x-portable-graymap",
"pko" => "application/ynd.ms-pkipko",
"pma" => "application/x-perfmon",
"pmc" => "application/x-perfmon",
"pml" => "application/x-perfmon",
"pmr" => "application/x-perfmon",
"pmw" => "application/x-perfmon",
"pnm" => "image/x-portable-anymap",
"pot" => "application/vnd.ms-powerpoint",
"ppm" => "image/x-portable-pixmap",
"pps" => "application/vnd.ms-powerpoint",
"ppt" => "application/vnd.ms-powerpoint",
"prf" => "application/pics-rules",
"ps" => "application/postscript",
"pub" => "application/x-mspublisher",
"qt" => "video/quicktime",
"ra" => "audio/x-pn-realaudio",
"ram" => "audio/x-pn-realaudio",
"ras" => "image/x-cmu-raster",
"rgb" => "image/x-rgb",
"rmi" => "audio/mid",
"roff" => "application/x-troff",
"rtf" => "application/rtf",
"rtx" => "text/richtext",
"scd" => "application/x-msschedule",
"sct" => "text/scriptlet",
"setpay" => "application/set-payment-initiation",
"setreg" => "application/set-registration-initiation",
"sh" => "application/x-sh",
"shar" => "application/x-shar",
"sit" => "application/x-stuffit",
"snd" => "audio/basic",
"spc" => "application/x-pkcs7-certificates",
"spl" => "application/futuresplash",
"src" => "application/x-wais-source",
"sst" => "application/vnd.ms-pkicertstore",
"stl" => "application/vnd.ms-pkistl",
"stm" => "text/html",
"svg" => "image/svg+xml",
"sv4cpio" => "application/x-sv4cpio",
"sv4crc" => "application/x-sv4crc",
"t" => "application/x-troff",
"tar" => "application/x-tar",
"tcl" => "application/x-tcl",
"tex" => "application/x-tex",
"texi" => "application/x-texinfo",
"texinfo" => "application/x-texinfo",
"tgz" => "application/x-compressed",
"tif" => "image/tiff",
"tiff" => "image/tiff",
"tr" => "application/x-troff",
"trm" => "application/x-msterminal",
"tsv" => "text/tab-separated-values",
"txt" => "text/plain",
"uls" => "text/iuls",
"ustar" => "application/x-ustar",
"vcf" => "text/x-vcard",
"vrml" => "x-world/x-vrml",
"wav" => "audio/x-wav",
"wcm" => "application/vnd.ms-works",
"wdb" => "application/vnd.ms-works",
"wks" => "application/vnd.ms-works",
"wmf" => "application/x-msmetafile",
"wps" => "application/vnd.ms-works",
"wri" => "application/x-mswrite",
"wrl" => "x-world/x-vrml",
"wrz" => "x-world/x-vrml",
"xaf" => "x-world/x-vrml",
"xbm" => "image/x-xbitmap",
"xla" => "application/vnd.ms-excel",
"xlc" => "application/vnd.ms-excel",
"xlm" => "application/vnd.ms-excel",
"xls" => "application/vnd.ms-excel",
"xlsx" => "vnd.ms-excel",
"xlt" => "application/vnd.ms-excel",
"xlw" => "application/vnd.ms-excel",
"xof" => "x-world/x-vrml",
"xpm" => "image/x-xpixmap",
"xwd" => "image/x-xwindowdump",
"z" => "application/x-compress",
"zip" => "application/zip"
);
$extension = end(explode('.', $file));
return $mimeTypes[$extension]; // return the array value
}
In the mail() after you get the $file variable set
$mime_type = $this->getMimeType($file);
// Change this
$header .= "Content-Type: application/octet-stream; name=\"".$filename."\"\r\n"; // use diff. tyoes here
// to this
$header .= "Content-Type: ".$mime_type."; name=\"".$filename."\"\r\n";
Hey, Phill, thanks for the contribution!
hi
thank you for the code first, but somehow it don’t work correctly for me
i can send the email but the message is empty and the attach file is emtpy also is written 0 kb
wat i did
i copy the code in a new file–> include this file
$sendit = new AttachmentEmail(‘[email protected]’,”testmail”,’blablala’, ‘file/images/test.jpg’);
if($sendit -> mail()){
echo “Your Message has been sent”;}
Exactly the same issue
Thanks for this code. Finally after wasting many hours today, this code solved my mail attachment problem. Now I can go to bed.
Gmail.com mailboxes don’t recieve messages using this class.
Can you help? What’s the reason may be?
Thank you
Thank you so much for this code! You have saved me many hours trying to fix my code to send e-mail attachments correctly.
Thanks, real timesaver and works like a buzz!
Peter
Thanks! I too saved a ton of time dealing with email headers and various email clients.
-Works in gmail, hotmail and mobile devices for me!
hi! that worked neatly! is there any way to send to (some of the) recipients as CCO?
thanks!
by CCO I mean BCC hehehe
I’d love to know how to do a BCC also.
Is there any way to format the text in the message?
Why this sends emails into spam folder instead of inbox? Any fix to this problem?
Darn, you’re terrific…. Your intro doesn’t BEGIN to describe the horrors of doing (or should I say TRYING to do? … w/o success in my case) email-with-attachments following either or both of “da book” or the 101 “scripts” out there. I started 6 or more hours of agony yesterday with the notion that “this can’t be that hard.” … Maybe, it isn’t – your code doesn’t look like a PhD in rocket science was required to put it together – which isn’t a dig – IT WORKS!! – but my experience says otherwise. That is, while I’m no PHP expert, I’m not altogether clueless – with you, copy/paste/run worked, but not with several instances of other-people’s-code. [I wanted to attach an HTM; maybe ZIP’s are easier, or at least different enough from HTM’s to cause repeated scripts failure.]
Yes!! You’ve saved (for those of us lucky enough to be brought to your site by Google) dozens, maybe hundreds (or in due time, thousands) of person-hours. If there’s any justice in the world, some wonderful things should be coming your way!!
great tutorial !!!!!!!!!!!!!!!!!. thank you so much for your efforts.
Great class for web developers 🙂
Thanks a lot for the class. it was exactly what i was looking for, and it worked like a charm 🙂
Hello Yang,
Simply great class, Highly recommended!
Thanks a lot man!
Great Class Indeed, worked perfect.
Thanks
Thanks so much for this. Saved me a lot of hassle!
Hi,
I’ve used. It is working but I’ve received attachment with corrupted.
Pls. help me.
thanks
Jagadesh
Excellent class!! Works perfectly right out of the box on all kinds of files. Simply brilliant. Thank you!
I’m getting 0kb attachment… why ?
Using UPLOAD file stuff before sending it… (simple stuff)
exemple:
$fileReal = $_FILES[‘file’][‘tmp_name’];
$fileName = $_FILES[‘file’][‘name’];
$sendIt = new AttachmentMail(“emailto”, “subject”, “body”, $fileReal, $fileName);
$sendIt->mail();
Works alright, however file comes with 0kb.
Help.
This mail script works fine with gmail….but not works with yahoo mail…. i cant download the file from yahoo….
Thanks man. It worked nicely. I just made a single function call as below.
function job_mail($from_name, $from_mail, $mailto, $replyto, &$subject, &$message, $mimetype, $attachment = ”, $attachment_filename = ”)
{
if (!empty($attachment)) {
$filename = empty($attachment_filename) ? basename($attachment) : $attachment_filename ;
$path = dirname($attachment);
$file = $path.’/’.$filename;
$file_size = filesize($file);
$handle = fopen($file, “r”);
$content = fread($handle, $file_size);
fclose($handle);
$content = chunk_split(base64_encode($content));
$uid = md5(uniqid(time()));
$name = basename($file);
$header = “From: “.$from_name.” \r\n”;
$header .= “Reply-To: “.$replyto.”\r\n”;
$header .= “MIME-Version: 1.0\r\n”;
$header .= “Content-Type: multipart/mixed; boundary=\””.$uid.”\”\r\n\r\n”;
$header .= “This is a multi-part message in MIME format.\r\n”;
$header .= “–“.$uid.”\r\n”;
$header .= “Content-type:text/html; charset=iso-8859-1\r\n”;
$header .= “Content-Transfer-Encoding: 7bit\r\n\r\n”;
$header .= $message.”\r\n\r\n”;
$header .= “–“.$uid.”\r\n”;
//$header .= “Content-Type: application/octet-stream; name=\””.$filename.”\”\r\n”; // use diff. tyoes here
$header .= “Content-Type: “.$mimetype . “; name=\””.$filename.”\”\r\n”;
$header .= “Content-Transfer-Encoding: base64\r\n”;
$header .= “Content-Disposition: attachment; filename=\””.$filename.”\”\r\n\r\n”;
$header .= $content.”\r\n\r\n”;
$header .= “–“.$uid.”–“;
if (mail($mailto, $subject, “”, $header)) {
return true;
} else {
return false;
}
} else {
$header = “From: “.($from_name).” \r\n”;
$header .= “Reply-To: “.($reply_to).”\r\n”;
if (mail($to, $subject, $message, $header)) {
return true;
} else {
return false;
}
}
}