PHP: Email Attachment Class

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.

44 thoughts on “PHP: Email Attachment Class”

  1. Pingback: A Basic PHP Contact Form Script

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

    $sendit = new AttachmentMail(‘[email protected]’, ‘Merry Christmas!’, ‘Hi’, ‘/home/racker/gift.jpg’);
    $sendit -> mail();

    1. many thanks for the class it is great

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

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

  3. Pingback: TemplateTweak :: Services

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

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

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

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

  7. 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”;}

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

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

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

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

  12. Hi,

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

    Pls. help me.

    thanks
    Jagadesh

  13. Excellent class!! Works perfectly right out of the box on all kinds of files. Simply brilliant. Thank you!

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

  15. 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;
    }

    }
    }

Comments are closed.

Scroll to Top