Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / PHP

Send HTML Mail with Attachments using PHP

5.00/5 (3 votes)
25 Nov 2022CPOL3 min read 51.7K   1K  
A PHP object for sending HTML mail with attachment
In this article, you will see a PHP object that can be used to send an HTML mail with attachment

Introduction

In the development of an Android application, I have had the necessity to send data to an Internet application, possibly with pictures attached. Sending a simple mail or HTML mail with PHP mail function is easy; the same function can accept message with embedded file(s), therefore it is the user who has to prepare the data through appropriate headers and encodings.

After some samples that I found on the WEB were not working or not generalised, I found a script (thanks to Antoine Bonnefoy) that not only sends file attachments but can also embed images: this script has been the starting point for creating the PHP class object of this article.

The Mail Object

The mail object is a PHP class with two functions for sending a mail: sendMail and sendMailParms; the second is only a wrapper for the first that permits to write the parameters in an array key=> value that are indifferent to the case (and the order).

The syntax for sending a mail is: sendMail($to, $from, $subject, $content, $files = '', $cc = '', $bcc = '') or sendMailParms($parms) where $parms can contain from none to all expected parameters:

Key Note
MailTo The recipient(s)
Subject The mail subject
Message The message, possibly in HTML format and with images (see below)
From The sender
Files The files to be attached (see below)
Cc The Carbon copy recipient(s)
Bcc The Blind carbon copy

i.e., sometime like this fragment that receive the data from a form that contains fields named Message , MailTo and possibly an uploaded file:

PHP
<?php
//	30/12/2016
include 'mailfile.php';
$msg = "";
foreach ($_REQUEST as $key => $value) $$key = $value;
$t = Array("N"=>"Text","H"=>"HTML","HI"=>"HTML with images");
$subject = $t[$type]." mail";
$parms = Array("subject"=>$subject,"mailto"=>$MailTo,
         "message"=>$Message,"from"=>"sender@mailoffice.it","files"=>$_FILES);
echo mail::sendMailParms($parms);
?>

HTML Mail and Embedded Images

The message is sent as HTML message if it contains HTML tags. For embedded images, the tag is the img tag where the src parameter must have the form:

src='cid:filename', cid: (Content-ID) tells the script that filename image is embedded in the mail.

HTML
<table>
<tr><td>Condor Informatique - Turin
<td><a href='www.condorinformatique.com' target='_blank'>
<img title='Condor Informatique - Turin' src='cid:images/condor.gif'></a>
<tr><td>Sermig - Turin
<td><a href='www.sermig.org' target='_blank'>
<br><img title='Sermig - ReTe' src='cid:images/sermig.jpg'></a>
<tr><td><img src=cid:images/info.png>See you later alligator<br>El Condor
</table>

Note that filename must contain the path for reading the image, but in the mail, the path is stripped by the script.

Below is the PHP fragment for finding the images contained in the message.

PHP
preg_match_all("/(<img .*?>)/i", $content,$out, PREG_PATTERN_ORDER);
$aEmbedFiles = Array();
foreach($out[1] as $cidFile) {
	$doc = new DOMDocument();
	$doc->loadHTML($cidFile);
	$imageTags = $doc->getElementsByTagName('img');
	foreach($imageTags as $tag) {
		$file = $tag->getAttribute('src');
		if (strtolower(substr($file,0,4)) == "cid:") {
			$file = substr($file,4);
			$aEmbedFiles[basename($file)] = $file;
		}
	}
}

The preg_match finds all img tags and stores them in $out array; I used the DOMDocument object of DOM function to extract the property src as it is complicated to extract by regular expression.

Only the file name of images with cid: are stored in the $aEmbedFiles array.

PHP
foreach($aEmbedFiles as $key => $value) {
	$content = str_replace($value, $key,$content);	// replace the path/file 
                                                    // with file only
}

The fragment code above replaces the path/filename with only the filename.

Attach Files

The possibly parameter Files is a list of files to upload; it can have three forms[1]:

  1. a file name
  2. an array of filenames
  3. an associative array of items uploaded via the HTTP POST (i.e., it can be the same associative array $_FILES)

In the first two cases, the function mimeType returns the MIME type of the file, based on the suffix of the file name[2]:

PHP
public static function mimeType($fl) {
	$mimeTypes = Array(".doc"=> "application/msword",".jpg"=>"image/jpeg",
    ".gif"=>"image/gif",".zip"=>"application/zip",".pdf"=>"application/pdf");
	$ext = strtolower(strrchr($fl, '.'));
	return (isset($mimeTypes[$ext])) ? $mimeTypes[$ext] : "application/octet-stream";
}

For the third case, the files uploaded, the mime type is stated on: $_FILES[...]['type'].

Using the Demo

The demo is a simple HTML page with a form[3] for sending a mail possibly in HTML format and uploading a file (limited to the size).

Notes

  1. ^This is an example of polymorphism of a PHP function.
  2. ^Instead of deprecated mime_content_type function and Fileinfo functions that is in library not by default in PHP.
  3. ^The form is generated by my JavaScript Form generator. See CodeProject A JavaScript Form Generator, or on my site.
    HTML
    <div id='result'></div>
    <span id='form' style='visibility:hidden'>
    Form,frm,Test PHP HTML Mailer,echo.php,receiveData,reset;
    T,Message,,251;
    H,MAX_FILE_SIZE;
    File,Attachment,Attachment file,30,.gif,.jpg, .png;
    T,MailTo,Receiver mail address,25;
    R,type,Message type,60,N=Normal,H=HTML,HI=HTML with images;
    B,fg_Cancel,&#x2718;,40,,Cancel Form;
    B,fg_Reset,&#x21B6;,40;
    B,Start,&#x270E;,40,,Go;
    Control,MailTo,Required,mail;
    Defaults,type=N,MAX_FILE_SIZE=5000,Message=See you later alligator\nEl Condor;
    </span>
    ...
    <script type='text/javascript'>
    formGen("result",$("form").innerHTML);
    ...

History

  • 14th March, 2017: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)