作成日:2006/05/27
2H.8 添付ファイルの送信
添付ファイルをメール送信する場合、メディアタイプとしてマルチパート( multipart )を使用します。 マルチパートとはメールのボディが複数のパートに分かれている事を意味しています。 添付ファイルを送信する場合を考えると、メールのボディが、 メールの本文と添付ファイルに分かれていると考えれば分かりやすいかと思います。
通常のメール送信では Content-Type として multipart/mixed を使用します。 これは、一般的なマルチパート・メディアタイプで個々のパートがそれぞれ別のメディアタイプを持つ事ができます。 以下にマルチパート・メディアタイプの例を示します。
マルチパート・メディアタイプの例
| メールヘッダ |
Return-Path: <y2sunlight@sample.ne.jp> (中略) MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="_Boundary_8878_42e9c503b20e3_" Content-Transfer-Encoding: 7bit |
|---|---|
| 空行 | |
| メールボティ |
--_Boundary_8878_42e9c503b20e3_ Content-Type: text/plain; charset=ISO-2022-JP Content-Transfer-Encoding: 7bit 空行 #$B$3$s$K$A$O#(B #$B$45!7y$$$+$,$G$9$+!)#(B --_Boundary_8878_42e9c503b20e3_ Content-Type: image/jpeg; name="bbSmall.jpg" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="bbSmall.jpg" /9j/4AAQSkZJRgABAQEASwBLAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcU (中略) 3BZ4uQqHVtjkbHNbj+R9MxL/AMOsvD+4X+lLnR9M5APydZ//AEL/AEoPOWmSvbtLAzcpU7HzHhQr e5dE0oXDEaZY5xj+zp/ShQf/2Q== --_Boundary_8878_42e9c503b20e3_-- |
この例では、1つのメールの中に2つのパートがあり、 1つは本文( text/plain )でもう1つは添付された画像データ( image/jpeg )です。 これらのパートについてこれまでに本章で説明した通りです。 メディアタイプ multipart/mixed の要点を以下に挙げます。
- ヘッダ部の Content-Type フィールドで multipart/mixed を宣言し、各パートの境界文字列( boundary )を指定します。
- 各パートは「--boundary境界文字列」で始まります。
- 全てのパートの終わりは「--boundary境界文字列--」で指定します。
- 各パートにはヘッダーとボディがあり、全体として異なったメディアをネストする構造が作れます。
用例:添付ファイル付きメール送信
この例ではスクリプトファイルをシフトJISで作成し、EUC環境下で実行しています。
スクリプトファイルのコード系と実行環境の内部コード系が同じ場合は、
mb_internal_encoding('文字セット')の呼び出しは必要ありません。
attach_mail.php
<?php
require "attach_mail.inc.php";
////////// 言語と文字コードの設定 //////////////////////////////
mb_language('ja'); // 必要に応じて使用言語を設定
mb_internal_encoding('SJIS'); // 必要に応じて内部コード系を設定
////////////////////////////////////////////////////////////////
$from_name = "送信元";
$from_addr = mb_encode_mimeheader($from_name); // ISO-2022-JP/Base64に変換
$from_addr .= " <y2sunlight@sample.ne.jp>";
$to_name = "送信先";
$to_addr = mb_encode_mimeheader($to_name); // ISO-2022-JP/Base64に変換
$to_addr .= " <info@y2sunlight.com>";
$subject = "こんにちは";
$body = "こんにちは\nご機嫌いかがですか?";
$filename = "img/bbSmall.jpg";
$mine = "image/jpeg";
($attach = file_get_contents($filename)) Or die("Open Error: $filename");
$filename = basename($filename);
$ret = Attach_Mail($from_addr, $to_addr, $subject, $body, $filename, $attach, $mine);
?>
<html><body>Attach_Mail</body></html>
attach_mail.inc.php
<?php
function Attach_Mail( $from, $to, $subject, $body, $filename, $attach, $mime="") {
$boundary = "_Boundary_" . uniqid(rand(1000,9999) . '_') . "_";
// 件名と本文のエンコード
$subject = mb_encode_mimeheader( $subject ); // ISO-2022-JP/Base64に変換
$body = mb_convert_encoding($body, 'ISO-2022-JP', 'auto'); // ISO-2022-JPに変換
// 添付データのエンコード
// 日本語のファイル名はRFC違反ですが、多くのメーラは理解します
$filename = mb_encode_mimeheader( $filename ); // ISO-2022-JP/Base64に変換
$attach = chunk_split(base64_encode($attach),76,"\n"); // Base64に変換し76Byte分割
// メディアタイプ未指定の場合は汎用のタイプを指定
if (!$mime) $mime = "application/octet-stream";
// ヘッダー
$header = "To: $to\n" .
"From: $from\n" .
"X-Mailer: PHP/" . phpversion() . "\n" .
"MIME-Version: 1.0\n" .
"Content-Type: Multipart/Mixed; boundary=\"$boundary\"\n" .
"Content-Transfer-Encoding: 7bit";
// マルチパート:本文
$mbody .= "--$boundary\n";
$mbody .= "Content-Type: text/plain; charset=ISO-2022-JP\n" .
"Content-Transfer-Encoding: 7bit\n";
$mbody .= "\n"; // 空行
$mbody .= "$body\n"; // 本文
// マルチパート:添付ファイル
$mbody .= "--$boundary\n";
$mbody .= "Content-Type: $mime; name=\"$filename\"\n" .
"Content-Transfer-Encoding: base64\n" .
"Content-Disposition: attachment; filename=\"$filename\"\n";
$mbody .= "\n"; // 空行
$mbody .= "$attach\n"; // 添付
// マルチパート:終わり
$mbody .= "--$boundary--\n";
return mail(NULL, $subject, $mbody, $header);
}
?>
上の例で実際に送信されるメールメッセージを下に示します。
< メール メッセージ >
Return-Path: <y2sunlight@sample.ne.jp> (中略) Subject: =?ISO-2022-JP?B?GyRCJDMkcyRLJEEkTxsoQg==?= To: =?ISO-2022-JP?B?GyRCQXc/LkBoGyhC?= <info@y2sunlight.com> From: =?ISO-2022-JP?B?GyRCQXc/Ljg1GyhC?= <y2sunlight@sample.ne.jp> X-Mailer: PHP/4.3.10 MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="_Boundary_8878_42e9c503b20e3_" Content-Transfer-Encoding: 7bit --_Boundary_8878_42e9c503b20e3_ Content-Type: text/plain; charset=ISO-2022-JP Content-Transfer-Encoding: 7bit #$B$3$s$K$A$O#(B #$B$45!7y$$$+$,$G$9$+!)#(B --_Boundary_8878_42e9c503b20e3_ Content-Type: image/jpeg; name="bbSmall.jpg" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="bbSmall.jpg" /9j/4AAQSkZJRgABAQEASwBLAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcU (中略) 3BZ4uQqHVtjkbHNbj+R9MxL/AMOsvD+4X+lLnR9M5APydZ//AEL/AEoPOWmSvbtLAzcpU7HzHhQr e5dE0oXDEaZY5xj+zp/ShQf/2Q== --_Boundary_8878_42e9c503b20e3_--
