Send email with attachment with PHP mail()
2010 July 16
by Richard Knop
I am posting this function mainly for my own reference. I am making sure I can just copy and paste this function in the future without having to go through that silly headers mambo jumbo again. This function will correctly map a file extension to a mime type and send both plain text and html versions of email. Here it is:
-
function sendEmailWithAttachment($toName, // recipient's name
-
$toEmail, // recipient's email
-
$fromName, // sender's name
-
$fromEmail, // sender's email
-
$emailText, // plain text email body
-
$emailHtml, // html email body
-
$fileToAttach /* path to a file you want to attach */)
-
{
-
-
$emailText = wordwrap($emailText, 70);
-
-
$headers = "To: $toName <$toEmail>\r\n";
-
$headers .= "From: $fromName <$fromEmail>\r\n";
-
-
$random_hash = md5(date('r', time()));
-
$headers .= 'Content-Type: multipart/mixed; boundary="PHP-mixed-' . $random_hash . '"';
-
-
$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",
-
"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('.', $fileToAttach));
-
$mimeType = $mimeTypes[$extension];
-
$fileName = end(explode('/', $fileToAttach));
-
-
$attachment = chunk_split(base64_encode(file_get_contents($fileToAttach)));
-
-
$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
-
-
$emailText
-
-
–PHP-alt-$random_hash
-
Content-Type: text/html; charset='iso-8859-1'
-
Content-Transfer-Encoding: 7bit
-
-
$emailHtml
-
-
–PHP-alt-$random_hash–
-
-
–PHP-mixed-$random_hash
-
Content-Type: application/$mimeType; name=$fileName
-
Content-Transfer-Encoding: base64
-
Content-Disposition: attachment
-
-
$attachment
-
–PHP-mixed-$random_hash–";
-
-
mail($toEmail, $subject, $output, $headers);
-
-
}
Hope somebody will find it useful.
from → PHP
2 Responses
leave one →
A very useful reference. However, boundaries should begin with two hyphens and end with 2 according to the mime rfc1341, the example above would not work without issues in e.g. gmail. I learned this the hard way by taking your code as a start point for my script where it simply put everything in the message body as text before fixing it.
Also filename should be in the content-disposition header, and you have redundant (invalid) “application/” in the content-type. You forgot the $subject parameter in the function construct but I guess you posted this code in a slight hurry, so I won’t critisize, it was overall very helpful as a rough reference to build on.
In regards to the hyphens comment, it may be I had soft ones corrupting my script, though I still prefer using proper ones.