PHPでメールを大量に送信する方法

  • 2020.02.16
  • PHP
PHPでメールを大量に送信する方法

PHPでメールを送信する場合、mail()やmb_send_mail()を使えば良いと思われがちですが、この関数は、大量のメールを送信するには向きません。
1通のメールを送信するたびにSMTPソケットをいったん閉じて開きなおすから仕組みだからです。
これは、メールサーバーにすごく負荷がかかります。

メールを大量に送信したい場合は、PHPメーラーのライブラリ「PHPMailer」を使用するとをおすすめします。

PHPMailerのライブラリは、下記からダウンロードができます。
https://github.com/PHPMailer/PHPMailer

PHPMailerは、SMTPメールサーバー経由でメールを送信します。

ソースと説明

PHPMailerのバージョンによって、若干、違います。
古いですが、私は、5.2.2を使ってます。

//ライブラリ読み込み
require "./PHPMailer/class.phpmailer.php";

//内部エンコーディング
mb_language("ja");
mb_internal_encoding("UTF-8");

//メール設定
$mailer = new PHPMailer();
$mailer->isSMTP();
// $mailer->SMTPSecure = "ssl";     // SSLメールの場合
$mailer->Host = "smtp.example.com"; // SMTPサーバー 内部のサーバーの場合はlocalhost
$mailer->Port = 587;                // ポート 25、587、465など
// $mailer->SMTPDebug = 2;          // デバッグモード 結果が出力されます。
$mailer->SMTPSecure = false;        // 方式
$mailer->SMTPAutoTLS = false;       // TLSの有無
$mailer->SMTPAuth = true;           // SMTP認証の有無
$mailer->Username = "ishigami";     // SMTP認証用のユーザ名
$mailer->Password = "xxxxxxxx";     // SMTP認証用のパスワード
$mailer->setFrom("ishigami@example.com", mb_encode_mimeheader("イシガミ", "UTF-8", "Q")); //メール差出人
$mailer->CharSet = "ISO-2022-JP";   // 文字コード
$mailer->WordWrap = 50;             // メールの折り返し

//件名
$mailer->Subject = mb_convert_encoding("件名", "ISO-2022-JP", "UTF-8");

//本文
$mailer->Body = mb_convert_encoding("本文", "ISO-2022-JP", "UTF-8");

//宛先
$ar_mail = array("mail1@example.com",
		 "mail2@example.com",
		 "mail3@example.com",
		 "mail4@example.com",
		 "mail5@example.com");

//メール送信
$j = 1;
for($i=0; $i<5; $i++){
	$to_mail = $ar_mail[$i];

	$mailer->AddAddress($to_mail); // 宛先を指定
	$mailer->send();               // メール送信
	$mailer->ClearAllRecipients(); // すべての宛先をクリア
	// $mailer->ClearAddresses();  // 宛先をクリア

	// 負荷防止のため、念のためスリープを入れる
	if($j>=50){
		sleep(2);
		$j = 0;
	}
	$j++;
}

PHPMailerを読み込みます。

//ライブラリ読み込み
require "./PHPMailer/class.phpmailer.php";

SMTPサーバーの設定を記述します。

//メール設定
$mailer = new PHPMailer();
$mailer->isSMTP();
// $mailer->SMTPSecure = "ssl";     // SSLメールの場合
$mailer->Host = "smtp.example.com"; // SMTPサーバー 内部のサーバーの場合はlocalhost
$mailer->Port = 587;                // ポート 25、587、465など
// $mailer->SMTPDebug = 2;          // デバッグモード 結果が出力されます。
$mailer->SMTPSecure = false;        // 方式
$mailer->SMTPAutoTLS = false;       // TLSの有無
$mailer->SMTPAuth = true;           // SMTP認証の有無
$mailer->Username = "ishigami";     // SMTP認証用のユーザ名
$mailer->Password = "xxxxxxxx";     // SMTP認証用のパスワード
$mailer->setFrom("ishigami@example.com", mb_encode_mimeheader("イシガミ", "UTF-8", "Q")); //メール差出人
$mailer->CharSet = "ISO-2022-JP";   // 文字コード
$mailer->WordWrap = 50;             // メールの折り返し

送るメールの内容を記述します。

//件名
$mailer->Subject = mb_convert_encoding("件名", "ISO-2022-JP", "UTF-8");

//本文
$mailer->Body = mb_convert_encoding("本文", "ISO-2022-JP", "UTF-8");

メールを送信します。

$mailer->AddAddress($to_mail); // 宛先を指定
$mailer->send();               // メール送信

ハマったこと

メール差出人の文字化け

対策としてmb_encodeを指定する。

mb_encode_mimeheader("イシガミ", "UTF-8", "Q")

メールの本文の文字化け

改行をせずに記述されているメールは、長すぎると文字化けを起こします。対策としてメールの折り返しを指定します。

$mailer->WordWrap = 50;

*メールが送れない原因を調べる場合は、デバッグモードを指定すると、SMTPサーバーの記述が間違っている等の原因がわかったりします、

参考サイト

https://pinkmonky.net/detail/?id=144
https://www.tomiryu.com/php/phpmailer/