在开发Android应用时,经常需要将数据发送到互联网应用,有时还会附带图片。使用PHP的mail函数发送简单邮件或HTML邮件相对容易,因为该函数可以接受带有嵌入文件的消息,因此用户需要通过适当的头部和编码来准备数据。
在互联网上找到的一些示例要么不起作用,要么不够通用。找到了一个脚本(感谢Antoine Bonnefoy),它不仅可以发送文件附件,还可以嵌入图片:这个脚本成为了本文PHP类对象的起点。
邮件对象是一个PHP类,包含两个用于发送邮件的函数:sendMail和sendMailParms;第二个函数只是第一个函数的包装器,允许将参数以数组形式key=>value写入,这些参数对大小写和顺序不敏感。
发送邮件的语法如下:
sendMail($to, $from, $subject, $content, $files = '', $cc = '', $bcc = '')
或者
sendMailParms($parms)
其中$parms可以包含从无到所有预期的参数:
Key | Note |
---|---|
MailTo | 收件人 |
Subject | 邮件主题 |
Message | 邮件内容,可能是HTML格式并包含图片(见下文) |
From | 发件人 |
Files | 要附加的文件(见下文) |
Cc | 抄送收件人 |
Bcc | 密送 |
例如,以下代码片段从包含名为Message、MailTo的字段的表单接收数据,可能还包含一个上传的文件:
<?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标签,则作为HTML邮件发送。对于嵌入图片,标签是img标签,其中src参数必须具有以下形式:
src='cid:filename'
cid:(Content-ID)告诉脚本filename图片嵌入在邮件中。
例如:
<table>
<tr>
<td>Condor Informatique - Turin</td>
<td><a href='www.condorinformatique.com' target='_blank'><img title='Condor Informatique - Turin' src='cid:images/condor.gif'></a></td>
</tr>
<tr>
<td>Sermig - Turin</td>
<td><a href='www.sermig.org' target='_blank'><br><img title='Sermig - ReTe' src='cid:images/sermig.jpg'></a></td>
</tr>
<tr>
<td><img src='cid:images/info.png'>See you later alligator<br>El Condor</td>
</tr>
</table>
请注意,filename必须包含读取图片的路径,但在邮件中,路径会被脚本剥离。
以下是用于查找消息中包含的图片的PHP片段:
preg_match_all("/()/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;
}
}
}
preg_match查找所有img标签并将它们存储在$out数组中;使用了DOMDocument对象的DOM函数来提取src属性,因为用正则表达式提取比较复杂。
只有带有cid:的图片文件名存储在$aEmbedFiles数组中。
以下是替换路径/文件名为仅文件名的代码片段:
foreach($aEmbedFiles as $key => $value) {
$content = str_replace($value, $key, $content);
// replace the path/file with file only
}
可能的参数Files是一个要上传的文件列表;它可以有三种形式:
在前两种情况下,函数mimeType返回文件的MIME类型,基于文件名的后缀:
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";
}
对于第三种情况,上传的文件,mime类型在$_FILES[...]['type']中指定。
演示是一个简单的HTML页面,包含一个表单,用于发送可能为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,✘,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);
...
</script>