web-dev-qa-db-ja.com

HTMLメールに画像を埋め込む方法

画像を埋め込んだHTMLメールを送信するコードを実装しようとしています。

私はすでに画像付きのシンプルなHTMLメールを試しましたが、この画像はサーバーから取得されました。

41
amol

PHPMailer のようなライブラリを使用してメールを送信することを強くお勧めします。
それは簡単で、ほとんどの問題を自動的に処理します。

埋め込み(インライン)画像の表示に関して、ここにあるのは それらのドキュメント

インライン添付

添付ファイルを追加する追加の方法があります。画像をデスクに組み込んでHTML形式の電子メールを作成する場合は、画像を添付してからタグをリンクする必要があります。たとえば、CID my-photoを使用して画像をインライン添付ファイルとして追加する場合、<img src="cid:my-photo" alt="my-photo" />を使用してHTML電子メール内で画像にアクセスします。

詳細は、インライン添付ファイルを追加する関数です。

$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('[email protected]', 'First Last');
  $mail->AddAddress('[email protected]', '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!
}
?>

編集:

あなたのコメントに関して、HTMLemailを埋め込み画像とともに送信する方法を尋ねたので、その方法の例を示しました。
先ほどお伝えしたライブラリは、SMTP以外の多くの方法を使用してメールを送信できます。
他の例については、 PHPMailerサンプルページ をご覧ください。

いずれにせよ、ライブラリでサポートされている方法で電子メールを送信したくない場合は、ライブラリを使用してメッセージを作成し、必要な方法で送信できます。

例えば:

メールを送信する行を置き換えることができます:

$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

お役に立てば幸いです。使用中に問題が発生した場合はお知らせください。

73
Carlos Lima

私はこの機能を使用して、私の手紙の中のすべての画像を見つけ、メッセージに添付します。

パラメータ: HTML(送信したい)を受け取ります。
Return:mail();で使用できる必要なHTMLおよびヘッダー

使用例:

define("DEFCALLBACKMAIL", "[email protected]"); // WIll be shown as "from".
$final_msg = preparehtmlmail($html); // give a function your html*

mail('[email protected]', '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);  
}
30
Arthur Halma

PHPMailerには、HTMLメールから画像を自動的に埋め込む機能があります。 HTMLを作成するときは、ファイルシステムでフルパスを指定する必要があります。

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

以下に自動的に変換されます:

<img src="cid:photo.png" alt="my photo" />
15
donis

Arthur Halmaの答えに基づいて、AppleのAndroid&iOS mail。

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);
}
2
djunod

メールをマルチパートMIMEとしてエンコードする必要があり、基本的にメールを添付ファイルとして添付できます。電子メールのcidでそれらを参照します。

または、メールに添付してURLを直接使用することはできませんが、スパマーがトリックを使用してメールアドレスの活性を検出するため、ほとんどのメールプログラムはこれをブロックします。

あなたはどの言語を言うのではありませんが、ここに一つあります

1
cletus

コーディングを気にせずに文字列変数を取得する方法を次に示します。

Mozilla Thunderbirdをお持ちの場合は、それを使用してHTMLイメージコードを取得できます。

私はここにスクリーンショット付きの小さなチュートリアルを書きました(これはpowershell用ですが、これは重要ではありません):

赤いxが表示されたHTML画像を含むPowerShellメール

そしてまた:

電子メールに画像を埋め込む方法

1
bgmCoder