PHP: Email Attachment Class

by Yang Yang on August 6, 2009

in Free PHP Classes & Library,PHP Tips & Tutorials

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.

Related Posts

{ 12 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

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

Leave a Comment

{ 2 trackbacks }

Previous post:

Next post: