実は結構難しいPHPでHTMLメールを送信する方法についてまとめてみた。
文字化けせずに3キャリアで絵文字も画像も半角カナもHTMLも表示できることが目標。
// テキストはJISコードに変換しマイムエンコードしてchunk_splitする。テキスト(html)に関してはquoted printableにエンコードする。 $from = mb_encode_mimeheader($from,"jis"); $to = mb_encode_mimeheader($to,"jis"); $subject = mb_encode_mimeheader($subject,"jis"); $textplain = chunk_split(base64_encode(mb_convert_encoding($textplain,"jis"))); $texthtml = imap_8bit(mb_convert_encoding($texthtml,"jis")); $imagename = mb_encode_mimeheader($imagename,"jis"); // 画像ファイルはマイムエンコードしchunk_splitする。 $imagedata = chunk_split(base64_encode($imagedata)); // バウンダリ(境界線)は21文字のランダム英字で作成。 $boundary1 = substr(md5(uniqid()),1,21); $boundary2 = substr(md5(uniqid()),1,21);
imgタグのsrcの値に関して
携帯の場合は<img src="cid:数字@数字">のように置換し、画像データをインライン添付しContent-ID: <数字@数字>とする。
PCの場合は外部のURLをSRC指定してもインライン添付でもどちらでも良い。
MIME-Version: 1.0 From: {$from} <from@systemexpress.co.jp> Subject: {$subject} To: {$to} <to@systemexpress.co.jp> Content-Type: multipart/alternative; boundary="{$boundary1}" --{$boundary1} Content-Type: text/plain; charset=ISO-2022-JP Content-Transfer-Encoding: base64 {$textplain} --{$boundary1} Content-Type: text/html; charset=ISO-2022-JP Content-Transfer-Encoding: quoted-printable {$texthtml} --{$boundary1}--
MIME-Version: 1.0 From: {$from} <from@systemexpress.co.jp> Subject: {$subject} To: {$to} <to@systemexpress.co.jp> Content-Type: multipart/related; boundary="{$boundary1}" Content-Transfer-Encoding: 7bit --{$boundary1} Content-Type: multipart/alternative; boundary="{$boundary2}" Content-Transfer-Encoding: 7bit --{$boundary2} Content-Type: text/plain; charset=ISO-2022-JP Content-Transfer-Encoding: base64 {$textplain} --{$boundary2} Content-Type: text/html; charset=ISO-2022-JP Content-Transfer-Encoding: quoted-printable {$texthtml} --{$boundary2}-- --{$boundary1} Content-Type: image/gif; name="{$imagename}" Content-Transfer-Encoding: base64 Content-ID: <{$cid}@{$cid}> {$imagedata} --{$boundary1}--
MIME-Version: 1.0 From: {$from} <from@systemexpress.co.jp> Subject: {$textplain} To: {$to} <to@systemexpress.co.jp> Content-Type: multipart/mixed; boundary="{$boundary1}" --{$boundary1} Content-Type: multipart/alternative; boundary="{$boundary2}" --{$boundary2} Content-Type: text/plain; charset=ISO-2022-JP Content-Transfer-Encoding: 7bit {$textplain} --{$boundary2} Content-Type: text/html; charset=ISO-2022-JP Content-Transfer-Encoding: quoted-printable {$texthtml} --{$boundary2}-- --{$boundary1} Content-Type: image/gif; name="{$imagename}" Content-Disposition: attachment; filename="{$imagename}" Content-Transfer-Encoding: base64 Content-ID: <{$cid}@{$cid}> {$imagedata} --{$boundary1}--
MIME-Version: 1.0 From: {$from} <from@systemexpress.co.jp> Subject: {$textplain} To: {$to} <to@systemexpress.co.jp> Content-Type: multipart/related; boundary="{$boundary1}" --{$boundary1} Content-Type: multipart/alternative; boundary="{$boundary2}" --{$boundary2} Content-Type: text/plain; charset=ISO-2022-JP Content-Transfer-Encoding: 7bit {$textplain} --{$boundary2} Content-Type: text/html; charset=ISO-2022-JP Content-Transfer-Encoding: quoted-printable {$texthtml} --{$boundary2}-- --{$boundary1} Content-Type: image/gif; name="{$imagename}" Content-Disposition: inline; filename="{$imagename}" Content-Transfer-Encoding: base64 Content-ID: <{$cid}@{$cid}> {$imagedata} --{$boundary1}--
最近インターネットメールを8ビット・データに対応させようという動きがあるが、その際に8ビットのままで利用するための定義である。
しかし、こうした活動は限定的なもので、厳密にはこの2つの方法は仕様違反だと思ってほしい。
上記は参考サイトからの引用だが、つまり「送信者はJISコードで送るべき。JISコードをマイムエンコードすれば絵文字も半角カナもHTMLも問題なく表示されるようにキャリアは対応するべき。」ということ。
mb_encode_mimeheaderとbase64_encodeの違いだが、実は両者ともやってることはそんなに変わらない。
echo mb_encode_mimeheader("マイムエンコードします","jis"); // =?ISO-2022-JP?B?GyRCJV4lJCVgJSglcyUzITwlSSQ3JF4kORsoQg==?= echo "=?ISO-2022-JP?B?".base64_encode("マイムエンコードします","jis")."?="; // =?ISO-2022-JP?B?GyRCJV4lJCVgJSglcyUzITwlSSQ3JF4kORsoQg==?=
quoted printableをするためにimap_8bit関数を使ったがimap_8bit関数はIMAP拡張モジュールが組み込まれていなければ使用できない。
IMAP拡張モジュールがない場合はyum install php-imapしてIMAP拡張モジュールをインストールする必要がある。
Copyright(C) systemexpress.co.jp All Rights Reserved. Author Takayuki Yukawa