|
|
|
| Много раз всплывал вопрос - как отправлять письмо в HTML-формате со встроенными в него изображениями, причем так, чтобы они не отображались во вложении. Если кому-то интересно можно отталкиваться при решении этой задачи от следующего скрипта.
<?php
// Отправляем почтовое сообщение
$picture[0] = "s_20040815135808.jpg";
$picture[1] = "s_20040815135939.jpg";
$mail_to = "sombody@somewhere.ru";
$thm = convert_cyr_string("Тема сообщения", "w", "k");
$html = "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">
<html>
<head><title>Почтовая рассылка</title></head>
<body><img src='cid:".md5($picture[0])."' border='0'>Тело сообщения<br><br><img src='cid:".md5($picture[1])."' border='0'></body>
</html>";
$html = convert_cyr_string($html, "w", "k");
if(send_mail($mail_to, $thm, $html, $picture))
echo "Успех ".date("d.m.Y H:i");
else
echo "Не отправлено";
function send_mail($mail_to, $thema, $html, $path)
{
$EOL = "\n";
$boundary = "--".md5(uniqid(time()));
$headers = "MIME-Version: 1.0;$EOL";
$headers .= "From: address@server.com$EOL";
// Вложение отсуствует
$headers .= "Content-Type: multipart/related; boundary=\"$boundary\"$EOL";
$multipart = "--{$boundary}$EOL";
$multipart .= "Content-Type: text/html; charset=koi8-r$EOL";
$multipart .= "Content-Transfer-Encoding: 8bit$EOL";
$multipart .= $EOL;
$multipart .= str_replace("\r\n", "\n", $html);
$multipart .= $EOL;
if (!empty($path))
{
for($i = 0; $i < count($path); $i++)
{
$file = file_get_contents($path[$i]);
$name = basename($path[$i]);
$multipart .= "$EOL--$boundary$EOL";
$multipart .= "Content-Type: image/jpeg; name=\"$name\"$EOL";
$multipart .= "Content-Transfer-Encoding: base64$EOL";
// Вложение отсуствует
// $multipart .= "Content-Disposition: attachment; filename=\"$name\"$EOL";
$multipart .= "Content-ID: <".md5($name).">$EOL";
$multipart .= $EOL;
$multipart .= chunk_split(base64_encode($file), 76, $EOL);
}
}
$multipart .= "$EOL--$boundary--$EOL";
echo $multipart;
if(!mail($mail_to, $thema, $multipart, $headers))
return False;
else
return True;
exit;
}
?>
|
| |
|
|
|
|
|
|
|
для: cheops
(17.11.2008 в 16:58)
| |
<?php
...
$multipart .= str_replace("\r\n", $EOL, $html);
...
| :-) | |
|
|
|
|
|
|
|
для: Root
(17.11.2008 в 17:06)
| | Это наборосок под хостинг конкретный заточенный - ещё не вылизывал его... Собственно сюда его помещаю, чтобы потом найти можно было быстро, а то проектов столько расплодилось, что искать в них небольшой участок кода достаточно сложно - на форуме быстрее получается. | |
|
|
|
|
|
|
|
для: cheops
(17.11.2008 в 17:10)
| |
<?
function Post($mail, $name, $reply, $subj, $text, $html, $img) {
$CRLF = substr(PHP_OS, 0, 3) != "WIN" ? "\n" : "\r\n";
$body = "";
$sender = "=?windows-1251?B?" . base64_encode($name) . "?= <" .$reply. ">";
$subj = "=?windows-1251?B?" . base64_encode($subj) . "?=";
$headers = "From: " . $sender . $CRLF;
$headers .= "Reply-To: " . $reply . $CRLF;
$headers .= "Return-path: " . $reply . $CRLF;
$headers .= "Mime-Version: 1.0" . $CRLF;
if ($html) {
$headers .= "Content-Type: multipart/alternative; boundary=\"partbody-1\"" . $CRLF . $CRLF;
$body .= "--partbody-1" . $CRLF . $CRLF;
$body .= "Content-type: text/plain; charset=\"" . DEFAULT_CHARSET . "\"" . $CRLF;
$body .= "Content-Transfer-Encoding: 8bit" . $CRLF . $CRLF;
$body .= $text . $CRLF;
$body .= "--partbody-1" . $CRLF;
$body .= "Content-Type: multipart/related; boundary=\"partbody-2\"; type=\"text/html\"" . $CRLF . $CRLF;
$body .= "--partbody-2" . $CRLF;
$body .= "Content-type: text/html; charset=\"" . DEFAULT_CHARSET . "\"" . $CRLF;
$body .= "Content-Transfer-Encoding: base64" . $CRLF . $CRLF;
$body .= chunk_split(base64_encode($html)) . $CRLF . $CRLF;
$body .= $img ? "--partbody-2" . $CRLF : "--partbody-2--" . $CRLF;
if ($img) {
$i = count($img);
foreach($img as $key) {
$i--;
$body .= "Content-Type: image/jpeg" . $CRLF;
$body .= "Content-ID: <pic_" . $key["id"] . ">" . $CRLF;
$body .= "Content-Transfer-Encoding: base64" . $CRLF;
$body .= "Content-Disposition: inline; filename=\"" . basename($key["img"]) . "\"" . $CRLF . $CRLF;
$file = $key["img"];
$f = fopen($file, "rb");
$body .= chunk_split(base64_encode(fread($f, filesize($file))));
$body .= $i ? "--partbody-2" . $CRLF : "--partbody-2--" . $CRLF;
}
}
$body .= "--partbody-1--" . $CRLF;
} else {
$headers .= "Content-type: text/plain; charset=\"" . DEFAULT_CHARSET . "\"" . $CRLF;
$headers .= "Content-Transfer-Encoding: 8bit" . $CRLF . $CRLF;
$body = $text . $CRLF;
}
mail($mail, $subj, $body, $headers);
}
?>
|
Вызов: адрес, имя, ответ, тема, шаблон текстовой версии, шаблон html-версии, массив изображений. | |
|
|
|
|
|
|
|
для: sim5
(17.11.2008 в 17:24)
| | Это вложенные в письмо несколько файлов, их можно будет сохранить на диск. Приведенный выше код позволяет создать такуюже функцию, но для встроенных изображений (их нельзя будет сохранить на диск). | |
|
|
|
|
|
|
|
для: cheops
(18.11.2008 в 11:58)
| | Все можно сохранить на диске, как файл письма. Прелесть в том, что это можно смотреть офлайне. Иначе, не будет доступа к серверу, значит в рассылке будут "дыры" :) | |
|
|
|
|
|
|
|
для: sim5
(18.11.2008 в 12:02)
| | Именно. Просто давно искал способ, чтобы аттач не отображался. Дело в том, что Outlook Express, если в аттаче имеются изображения их после основного содержимого отображает - это нарушает HTML-верстку, да и смысла в этом нет, если изображения используются в HTML-содержимом письма. | |
|
|
|
|
|
|
|
для: cheops
(18.11.2008 в 12:09)
| | Так у меня тоже самое и есть (Content-Disposition: inline;...) А сами части тела письма (текстовая и html версии) формируются с теми же данными, что и почтовое сообщение (в частности им передается тот же массив изображений, что и в функцию, для CID). Для Смарти, например, достаточно отправить обработанные шаблоны в функцию ($smarty_mail->fetch("template.tpl").
Собственно добавить еще третью часть тела письма (как прикрепление) тоже труда не составит. | |
|
|
|
|
|
|
|
для: sim5
(18.11.2008 в 12:28)
| | Добавлю лишь, что multipart/alternative; нужно ещё заменить на multipart/related; | |
|
|
|
|
|
|
|
для: cheops
(18.11.2008 в 13:26)
| | Нет, не надо, так как у меня отправляется две разных части - текстовая весия, а затем html. Единственно, так это указать multipart/related; для html-части, что и сделано. | |
|
|
|