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
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.
<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.
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.
foreach($aEmbedFiles as $key => $value) {
$content = str_replace($value, $key,$content);
}
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]:
- a file name
- an array of filenames
- 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]:
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
- ^This is an example of polymorphism of a PHP function.
- ^Instead of deprecated
mime_content_type
function and Fileinfo
functions that is in library not by default in PHP. - ^The form is generated by my JavaScript Form generator. See CodeProject A JavaScript Form Generator, or on my site.
<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,✘,40,,Cancel Form;
B,fg_Reset,↶,40;
B,Start,✎,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