PHP: Email Attachment Class

by Yang Yang on August 6, 2009

in Free PHP Classes & Library, PHP Tips & Tutorials

Share This Article:
Subscribe to Kavoir: blog feed

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 = 'yours@email.com';
	private $from_name = 'Your Name';
	private $reply_to = 'yours@email.com';
	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('marry@example.com', '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.

Share This Article:
Subscribe to Kavoir: blog feed

You should also read:

{ 35 comments… read them below or add one }

Alex January 18, 2010 at 11:44 pm

Nice little class, I like it

Reply

Yang Yang January 26, 2010 at 1:20 pm

Glad to know! :)

Reply

Tag January 23, 2010 at 7:00 pm

Shouldn’t that be AttachmentMail instead of AttachmentEmail .. (E)

$sendit = new AttachmentMail(‘marry@example.com’, ‘Merry Christmas!’, ‘Hi’, ‘/home/racker/gift.jpg’);
$sendit -> mail();

Reply

Yang Yang January 23, 2010 at 8:42 pm

Thanks, got it fixed. :)

Reply

Dani January 29, 2010 at 3:19 am

Just what I was looking for. Thanks dude!

Reply

Nick Web February 15, 2010 at 6:02 pm

This worked perfect, zip, pdf, whatever I need to e-mail! Thanks so much!

Reply

Yang Yang February 26, 2010 at 6:13 pm

Glad it works for all of you!

Reply

matt March 29, 2010 at 1:12 pm

Perfect! I took the liberty of modifying it to handle multiple attachments. Thanks!

Reply

Yang Yang March 31, 2010 at 3:18 pm

Yeah, multiple attachments, that’d be a great idea for enhancement. Thanks!

Reply

phantom September 28, 2010 at 6:01 pm

many thanks for the class it is great

-> matt care to share how the multiple attachments mod? that would be great thanks

Reply

Chris March 31, 2010 at 5:43 am

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..!

Reply

Yang Yang March 31, 2010 at 3:20 pm

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.

Reply

Endre July 4, 2010 at 1:08 am

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

Reply

Yasitha Dinushi October 18, 2010 at 2:13 pm

This works great , Thank you

Reply

Phill Pafford November 1, 2010 at 11:23 pm

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";

Reply

Yang Yang November 2, 2010 at 4:00 pm

Hey, Phill, thanks for the contribution!

Reply

Fred December 19, 2010 at 10:03 pm

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(‘test@hotmail.com’,”testmail”,’blablala’, ‘file/images/test.jpg’);
if($sendit -> mail()){
echo “Your Message has been sent”;}

Reply

Zeeshan A Zakaria December 25, 2010 at 12:24 pm

Thanks for this code. Finally after wasting many hours today, this code solved my mail attachment problem. Now I can go to bed.

Reply

Alex December 29, 2010 at 4:33 am

Gmail.com mailboxes don’t recieve messages using this class.
Can you help? What’s the reason may be?
Thank you

Reply

Josh February 10, 2011 at 12:20 pm

Thank you so much for this code! You have saved me many hours trying to fix my code to send e-mail attachments correctly.

Reply

Arnhem March 10, 2011 at 10:14 pm

Thanks, real timesaver and works like a buzz!

Peter

Reply

Mike Wirth April 7, 2011 at 9:13 pm

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!

Reply

roy April 18, 2011 at 10:13 pm

hi! that worked neatly! is there any way to send to (some of the) recipients as CCO?

thanks!

Reply

roy April 18, 2011 at 10:14 pm

by CCO I mean BCC hehehe

Reply

Mike Wirth April 24, 2011 at 6:15 pm

I’d love to know how to do a BCC also.

Reply

Mike Wirth May 2, 2011 at 1:14 am

Is there any way to format the text in the message?

Reply

Kashif Javed May 12, 2011 at 1:34 pm

Why this sends emails into spam folder instead of inbox? Any fix to this problem?

Reply

Phil Fusco June 2, 2011 at 11:51 pm

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!!

Reply

asif hameed June 13, 2011 at 8:55 pm

great tutorial !!!!!!!!!!!!!!!!!. thank you so much for your efforts.

Reply

Zahid Habib August 16, 2011 at 6:15 pm

Great class for web developers :)

Reply

Sarika August 17, 2011 at 5:44 pm

Thanks a lot for the class. it was exactly what i was looking for, and it worked like a charm :)

Reply

Sanjay Chauhan September 6, 2011 at 9:17 pm

Hello Yang,
Simply great class, Highly recommended!
Thanks a lot man!

Reply

Naveed Ahmed October 11, 2011 at 8:51 pm

Great Class Indeed, worked perfect.

Thanks

Reply

Jack Rugile December 14, 2011 at 3:34 am

Thanks so much for this. Saved me a lot of hassle!

Reply

Jagadesh January 25, 2012 at 12:18 pm

Hi,

I’ve used. It is working but I’ve received attachment with corrupted.

Pls. help me.

thanks
Jagadesh

Reply

Leave a Comment

{ 2 trackbacks }

Previous post:

Next post: