Как встраивать изображения в HTML письмо - PullRequest
39 голосов
/ 05 декабря 2009

Я пытаюсь реализовать код для отправки электронного письма в формате HTML со встроенным изображением.

Я уже пробовал использовать простое HTML-письмо с изображением, но это изображение взято с сервера.

Ответы [ 6 ]

72 голосов
/ 05 декабря 2009

Я настоятельно рекомендую использовать такую ​​библиотеку, как PHPMailer для отправки электронных писем.
Это проще и решает большинство вопросов автоматически для вас.

Что касается отображения встроенных (встроенных) изображений, вот что есть на их документации :

Встроенные вложения

Существует еще один способ добавить крепление. Если вы хотите сделать HTML электронная почта с изображениями, включенными в стол, необходимо прикрепить изображение, а затем привязать тег к нему. За Например, если вы добавляете изображение как встроенное Вложение с CID my-photo, вы будет иметь доступ к нему в электронной почте HTML с <img src="cid:my-photo" alt="my-photo" />.

Подробно, вот функция для добавления встроенное вложение:

$mail->AddEmbeddedImage(filename, cid, name);
//By using this function with this example's value above, results in this code:
$mail->AddEmbeddedImage('my-photo.jpg', 'my-photo', 'my-photo.jpg ');

Чтобы дать вам более полный пример того, как это будет работать:

<?php
require_once('../class.phpmailer.php');
$mail = new PHPMailer(true); // the true param means it will throw exceptions on     errors, which we need to catch

$mail->IsSMTP(); // telling the class to use SMTP

try {
  $mail->Host       = "mail.yourdomain.com"; // SMTP server
  $mail->Port       = 25;                    // set the SMTP port
  $mail->SetFrom('name@yourdomain.com', 'First Last');
  $mail->AddAddress('whoto@otherdomain.com', 'John Doe');
  $mail->Subject = 'PHPMailer Test';

  $mail->AddEmbeddedImage("rocks.png", "my-attach", "rocks.png");
  $mail->Body = 'Your <b>HTML</b> with an embedded Image: <img src="cid:my-attach"> Here is an image!';

  $mail->AddAttachment('something.zip'); // this is a regular attachment (Not inline)
  $mail->Send();
  echo "Message Sent OK<p></p>\n";
} catch (phpmailerException $e) {
  echo $e->errorMessage(); //Pretty error messages from PHPMailer
} catch (Exception $e) {
  echo $e->getMessage(); //Boring error messages from anything else!
}
?>

Edit:

Что касается вашего комментария, вы спросили, как отправить HTML по электронной почте со встроенными изображениями, поэтому я привел вам пример того, как это сделать.
Библиотека, о которой я вам рассказывал, может отправлять электронные письма, используя множество методов, отличных от SMTP.
Посмотрите на страницу PHPMailer Example для других примеров.

Так или иначе, если вы не хотите отправлять электронную почту способами, поддерживаемыми библиотекой, вы можете (должны) по-прежнему использовать библиотеку для создания сообщения, а затем отправляете его так, как хотите.

Например:

Вы можете заменить строку, которая отправляет электронное письмо:

$mail->Send();

С этим:

$mime_message = $mail->CreateBody(); //Retrieve the message content
echo $mime_message; // Echo it to the screen or send it using whatever method you want

Надеюсь, это поможет. Дайте мне знать, если у вас возникнут проблемы с его использованием.

30 голосов
/ 22 октября 2009

Я использую эту функцию, чтобы найти все изображения в моем письме и прикрепить его к сообщению.

Параметры: Принимает ваш HTML (который вы хотите отправить);
Возврат: Необходимые HTML и заголовки, которые вы можете использовать в mail();

Пример использования:

define("DEFCALLBACKMAIL", "yourmail@yourdomain.com"); // WIll be shown as "from".
$final_msg = preparehtmlmail($html); // give a function your html*

mail('your@mail.com', 'your subject', $final_msg['multipart'], $final_msg['headers']); 
// send email with all images from html attached to letter


function preparehtmlmail($html) {

  preg_match_all('~<img.*?src=.([\/.a-z0-9:_-]+).*?>~si',$html,$matches);
  $i = 0;
  $paths = array();

  foreach ($matches[1] as $img) {
    $img_old = $img;

    if(strpos($img, "http://") == false) {
      $uri = parse_url($img);
      $paths[$i]['path'] = $_SERVER['DOCUMENT_ROOT'].$uri['path'];
      $content_id = md5($img);
      $html = str_replace($img_old,'cid:'.$content_id,$html);
      $paths[$i++]['cid'] = $content_id;
    }
  }

  $boundary = "--".md5(uniqid(time()));
  $headers .= "MIME-Version: 1.0\n";
  $headers .="Content-Type: multipart/mixed; boundary=\"$boundary\"\n";
  $headers .= "From: ".DEFCALLBACKMAIL."\r\n";
  $multipart = '';
  $multipart .= "--$boundary\n";
  $kod = 'utf-8';
  $multipart .= "Content-Type: text/html; charset=$kod\n";
  $multipart .= "Content-Transfer-Encoding: Quot-Printed\n\n";
  $multipart .= "$html\n\n";

  foreach ($paths as $path) {
    if(file_exists($path['path']))
      $fp = fopen($path['path'],"r");
      if (!$fp)  {
        return false;
      }

    $imagetype = substr(strrchr($path['path'], '.' ),1);
    $file = fread($fp, filesize($path['path']));
    fclose($fp);

    $message_part = "";

    switch ($imagetype) {
      case 'png':
      case 'PNG':
            $message_part .= "Content-Type: image/png";
            break;
      case 'jpg':
      case 'jpeg':
      case 'JPG':
      case 'JPEG':
            $message_part .= "Content-Type: image/jpeg";
            break;
      case 'gif':
      case 'GIF':
            $message_part .= "Content-Type: image/gif";
            break;
    }

    $message_part .= "; file_name = \"$path\"\n";
    $message_part .= 'Content-ID: <'.$path['cid'].">\n";
    $message_part .= "Content-Transfer-Encoding: base64\n";
    $message_part .= "Content-Disposition: inline; filename = \"".basename($path['path'])."\"\n\n";
    $message_part .= chunk_split(base64_encode($file))."\n";
    $multipart .= "--$boundary\n".$message_part."\n";

  }

  $multipart .= "--$boundary--\n";
  return array('multipart' => $multipart, 'headers' => $headers);  
}
15 голосов
/ 05 декабря 2009

PHPMailer имеет возможность автоматически вставлять изображения из вашей электронной почты в формате HTML. При написании HTML вы должны указать полный путь в файловой системе:

<img src="/var/www/host/images/photo.png" alt="my photo" />

Будет автоматически преобразовано в:

<img src="cid:photo.png" alt="my photo" />
2 голосов
/ 28 августа 2015

Основываясь на ответе Артура Халмы, я сделал следующее, что правильно работает с почтой Apple, Android и iOS.

define("EMAIL_DOMAIN", "yourdomain.com");

public function send_email_html($to, $from, $subject, $html) {
  preg_match_all('~<img.*?src=.([\/.a-z0-9:_-]+).*?>~si',$html,$matches);
  $i = 0;
  $paths = array();
  foreach ($matches[1] as $img) {
    $img_old = $img;
    if(strpos($img, "http://") == false) {
      $uri = parse_url($img);
      $paths[$i]['path'] = $_SERVER['DOCUMENT_ROOT'].$uri['path'];
      $content_id = md5($img);
      $html = str_replace($img_old,'cid:'.$content_id,$html);
      $paths[$i++]['cid'] = $content_id;
    }
  }
  $uniqid   = md5(uniqid(time()));
  $boundary = "--==_mimepart_".$uniqid;

  $headers = "From: ".$from."\n".
  'Reply-to: '.$from."\n".
  'Return-Path: '.$from."\n".
  'Message-ID: <'.$uniqid.'@'.EMAIL_DOMAIN.">\n".
  'Date: '.gmdate('D, d M Y H:i:s', time())."\n".
  'Mime-Version: 1.0'."\n".
  'Content-Type: multipart/related;'."\n".
  '  boundary='.$boundary.";\n".
  '  charset=UTF-8'."\n".
  'X-Mailer: PHP/' . phpversion();

  $multipart = '';
  $multipart .= "--$boundary\n";
  $kod = 'UTF-8';
  $multipart .= "Content-Type: text/html; charset=$kod\n";
  $multipart .= "Content-Transfer-Encoding: 7-bit\n\n";
  $multipart .= "$html\n\n";
  foreach ($paths as $path) {
    if (file_exists($path['path']))
      $fp = fopen($path['path'],"r");
      if (!$fp)  {
        return false;
      }
    $imagetype = substr(strrchr($path['path'], '.' ),1);
    $file = fread($fp, filesize($path['path']));
    fclose($fp);
    $message_part = "";
    switch ($imagetype) {
      case 'png':
      case 'PNG':
            $message_part .= "Content-Type: image/png";
            break;
      case 'jpg':
      case 'jpeg':
      case 'JPG':
      case 'JPEG':
            $message_part .= "Content-Type: image/jpeg";
            break;
      case 'gif':
      case 'GIF':
            $message_part .= "Content-Type: image/gif";
            break;
    }
    $message_part .= "; file_name = \"$path\"\n";
    $message_part .= 'Content-ID: <'.$path['cid'].">\n";
    $message_part .= "Content-Transfer-Encoding: base64\n";
    $message_part .= "Content-Disposition: inline; filename = \"".basename($path['path'])."\"\n\n";
    $message_part .= chunk_split(base64_encode($file))."\n";
    $multipart .= "--$boundary\n".$message_part."\n";
  }
  $multipart .= "--$boundary--\n";
  mail($to, $subject, $multipart, $headers);
}
1 голос
/ 02 августа 2013

Вот способ получить строковую переменную, не беспокоясь о кодировании.

Если у вас есть Mozilla Thunderbird , вы можете использовать его для получения html-кода изображения.

Я написал небольшое учебное пособие со снимком экрана (это для powershell, но это не имеет значения):

электронная почта powershell с html-изображением, отображающим красный цвет x

И снова:

Как вставлять изображения в электронную почту

1 голос
/ 05 декабря 2009

Вы должны закодировать свою электронную почту как составную mime, а затем в основном можете прикреплять электронные письма как вложения. Вы ссылаетесь на них по электронной почте в cid.

В качестве альтернативы вы не могли бы прикрепить их к электронной почте и использовать URL-адреса напрямую, но большинство почтовых программ блокируют это, поскольку спамеры используют прием для определения жизнеспособности адресов электронной почты.

Вы не говорите, на каком языке, но вот один пример .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...