エントリー

PHPで添付ファイル付きメールを送信

PHPには mb_send_mail() という命令があり、これを使うと簡単に日本語メールを送信することができます。ただし添付ファイルには対応していないので、添付ファイルを扱う場合は利用できません。

大抵の解説では「mail() 関数を使ってメールヘッダを自力で書けば添付ファイルも送れますが、面倒なのでPEARなどを使いましょう。」とか書かれています。ですが例によってPEARは使いたくないので、自力でヘッダなどを書いてみた。

<?php

//マイムタイプ定義
$mime_content_types = array(
  'ez'      => 'application/andrew-inset',
  'atom'    => 'application/atom+xml',
  'atomcat' => 'application/atomcat+xml',
  ~略~
  'avi'     => 'video/x-msvideo',
  'movie'   => 'video/x-sgi-movie',
  'ice'     => 'x-conference/x-cooltalk'
);

//送信先メールアドレス
$to = 'example@example.com';

//送信元メールアドレス
$from = 'example@example.com';

//件名
$subject = '添付ファイルのテスト';

//メール本文
$message  = "テストメール。\n";
$message .= "添付ファイル送信のテストです。\n";

//添付ファイル
$files = array('images/test.gif');

//件名・本文をエンコード
$subject = mb_convert_encoding($subject, 'JIS', 'UTF-8');
$message = mb_convert_encoding($message, 'JIS', 'UTF-8');

$subject = '=?iso-2022-jp?B?' . base64_encode($subject) . '?=';

//バウンダリ文字列を定義
if (empty($files)) {
  $boundary = null;
} else {
  $boundary = md5(uniqid(rand(), true));
}

//メールボディを定義
if (empty($files)) {
  $body = $message;
} else {
  $body  = "--$boundary\n";
  $body .= "Content-Type: text/plain; charset=\"iso-2022-jp\"\n";
  $body .= "Content-Transfer-Encoding: 7bit\n";
  $body .= "\n";
  $body .= "$message\n";

  foreach($files as $file) {
    if (!file_exists($file)) {
      continue;
    }

    $info    = pathinfo($file);
    $content = $mime_content_types[$info['extension']];

    $filename = basename($file);

    $body .= "\n";
    $body .= "--$boundary\n";
    $body .= "Content-Type: $content; name=\"$filename\"\n";
    $body .= "Content-Disposition: attachment; filename=\"$filename\"\n";
    $body .= "Content-Transfer-Encoding: base64\n";
    $body .= "\n";
    $body .= chunk_split(base64_encode(file_get_contents($file))) . "\n";
  }

  $body .= '--' . $boundary . '--';
}

//メールヘッダを定義
$header  = "X-Mailer: PHP5\n";
$header .= "From: $from\n";
$header .= "MIME-Version: 1.0\n";
if (empty($files)) {
  $header .= "Content-Type: text/plain; charset=\"iso-2022-jp\"\n";
} else {
  $header .= "Content-Type: multipart/mixed; boundary=\"$boundary\"\n";
}
$header .= "Content-Transfer-Encoding: 7bit";

//メール送信
if (mail($to, $subject, $body, $header)) {
  echo 'メールが送信されました。';
} else {
  echo 'メールの送信に失敗しました。';
}

?>

プログラムはUTF-8で書くことを前提としています。

$mime_content_types の定義内容の全文はPHPでマイムタイプを自動判別に記載しています。添付ファイルのマイムタイプは常に application/octet-stream でも大丈夫っぽいですが、正しく定義した方が好ましいようです。

添付ファイルは $files に配列の形式でいくつでも設定できます。添付ファイルが無い場合、それにあわせてメールヘッダなどの内容も自動で変化します。

特に問題なく送信できましたが、書いたばかりなので近々じっくりテストしてみます。

ページ移動

ユーティリティ

カテゴリー

検索

エントリー検索フォーム
キーワード

過去ログ

過去ログ表示フォーム
キーワード

Feed