このシリーズでは、色々なプログラムでメールを送る方法を紹介していきます。 今回はPHPでメールを送る方法として、PHPMailerの使い方を紹介します。
目次
本記事では、メールサーバとは別のサーバでプログラムを実行します。
メールサーバに接続可能でプログラムが実行できる環境であれば、クライアントPCやメールサーバと同一環境でも問題ありません。
実行環境のOSは「AlmaLinux 8.10」を使用しています。
# cat /etc/redhat-release
AlmaLinux release 8.10 (Cerulean Leopard)
OSは「AlmaLinux 8.9」、SMTPサーバとして「postfix 3.5.8」を使用しています。
# cat /etc/redhat-release
AlmaLinux release 8.9 (Midnight Oncilla)
# postconf | grep mail_version
mail_version = 3.5.8
milter_macro_v = $mail_name $mail_version
プログラムの実行環境とメールサーバ間は587ポートで接続し、SMTP AUTHで認証します。
シンプルですが今回の構成を図にするとこんな感じです。
PHPはHypertext Preprocessorの略で、主にWeb開発に用いられるサーバーサイドスクリプト言語です。HTMLの中に埋め込んで記述することもでき、動的なWEBページを作成することができる強力なツールです。
PHPは、組み込みの関数や外部ライブラリを使用することで、簡単にメールを送信する機能を実装できます。シンプルなスクリプトから本格的なメール配信システムまで、幅広い用途に対応可能です。 PHPでメールを送信する方法としては、以下のような選択肢が考えられます。
PHPに標準で用意されているmail()関数を使って、簡単なメール送信が可能です。
メリット
デメリット
PHPMailerは、PHPでメールを送信するための非常に人気のあるライブラリで、SMTPの設定や認証、添付ファイルの送信など、豊富な機能を提供しています。
メリット
デメリット
SwiftMailerもPHPでのメール送信に広く使われているライブラリです。PHPMailerと似た機能を提供し、高度なメール送信が可能です。
メリット
デメリット
PHPでメールを送信したい場合、組み込みのmail()関数を直接利用するのが最も手軽です。しかし、mail()関数は設定がシステムに依存するため、柔軟性や信頼性の面で課題がある場合もあります。そのため、細かな設定やエラーハンドリングが必要な場合には、SMTPサーバーの利用を前提とした外部ライブラリを利用するのが一般的です。
今回は複雑なメール送信処理を必要としないため、SMTP認証機能に対応でき、設定もシンプルで分かりやすいPHPMailerを使用したいと思います。
PHPでメールを送るプログラムを作ります。必要なものは下記の3つとなるので、環境に合わせて導入してください。
今回使用するPHPのバージョンは「7.2.24」です。
# php -v
PHP 7.2.24 (cli) (built: Oct 22 2019 08:28:36) ( NTS )
他のバージョンでは実行できない可能性がありますのでご了承下さい。
まずはSMTPの接続情報とエンベロープFROM、ヘッダFROMを記載するための設定ファイルを作成します。
値は実際の送信環境に合わせて下さい。
# vi smtp_config.php
※ここから
-------
'SERVER_HOST_NAME', // SMTPサーバのホスト名
'username' => 'USERNAME@DOMAIN', // SMTPユーザ名
'password' => 'YOUR_PASSWORD', // SMTPパスワード
'port' => 587, // SMTPポート番号
'use_tls' => false, // TLS使用有無設定。使用する場合はtrue
'from_email' => ' HEADER_FROM_ADD ', // ヘッダーFROMメールアドレス
'from_name' => 'YOUR_NAME', // ヘッダーFROM表示名
'envelope_from' => 'ENVELOPE_FROM_ADD’, // エンベロープFromメールアドレス
];
?>
-------
※ここまで
続いてPHPのプログラムを作成します。
本記事では「send_mail.php」という名前で作成しますが、お好きな名前で作成してOKです。
# # vi send_mail.php
※ここから
-------
"; exit(1); } $to = $argv[1]; $subject = $argv[2]; $message = $argv[3]; $mail = new PHPMailer(true); try { // デバッグ出力を有効化 $mail->SMTPDebug = 0; $mail->isSMTP(); $mail->Host = $config['host']; $mail->SMTPAuth = true; $mail->Username = $config['username']; $mail->Password = $config['password']; // TLSの使用判定 if ($config['use_tls']) { $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; } else { $mail->SMTPSecure = ''; } $mail->Port = $config['port']; $mail->setFrom($config['from_email'], $config['from_name']); $mail->Sender = $config['envelope_from']; $mail->addAddress($to); $mail->isHTML(false); $mail->Subject = $subject; $mail->Body = $message; $mail->XMailer = ' '; $mail->send(); echo "Message has been sent to $to
"; } catch (Exception $e) { echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}
"; } ?> -------
※ここまで
PHPでも引数として「Toアドレス」、「件名」、「メール本文」を末尾に追加するようにしています。 実行例は下記のとおりです。
php send_mail.sh "xxxxxxx@xxx.xxx" "Test Mail From PHP" "PHP"
送信に成功すると、下記のようなメッセージが出力されます。
Message has been sent to xxxxxxx@xxx.xxx
送ったメールを確認すると届いていることが分かります。
こちらも指定したヘッダFromで届いていますね。
送信に失敗してしまった場合、設定ファイルが間違っている可能性があるため「smtp_config.php」の内容を見直して下さい。
また、「send_mail.php」の「$mail->SMTPDebug = 0;」を「$mail->SMTPDebug = 2;」とすることでデバッグモードを有効にできます。
デバッグモードにすることで、出力される内容からどこで失敗しているか分かりやすくなるため、必要に応じて使用してみてください。
正常に実行された場合、デバッグモードだと下記のように出力されます。
# php send_mail.php "xxxxxxx@xxx.xxx" "Test Mail From PHP" "PHP"
yyyy-mm-dd hh:mm:ss SERVER -> CLIENT: 220 MAIL_HOST ESMTP Postfix (AlmaLinux)
yyyy-mm-dd hh:mm:ss SERVER -> CLIENT: 220 MAIL_HOST ESMTP Postfix (AlmaLinux)
yyyy-mm-dd hh:mm:ss CLIENT -> SERVER: EHLO YOUR_HOST
yyyy-mm-dd hh:mm:ss SERVER -> CLIENT: 250-MAIL_HOST
250-PIPELINING
250-SIZE 10240000
250-ETRN
250-AUTH PLAIN LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-DSN
250 SMTPUTF8
yyyy-mm-dd hh:mm:ss CLIENT -> SERVER: AUTH LOGIN
yyyy-mm-dd hh:mm:ss SERVER -> CLIENT: 334 VXNlcm5hbWU6
yyyy-mm-dd hh:mm:ss CLIENT -> SERVER: [credentials hidden]
yyyy-mm-dd hh:mm:ss SERVER -> CLIENT: 334 UGFzc3dvcmQ6
yyyy-mm-dd hh:mm:ss CLIENT -> SERVER: [credentials hidden]
yyyy-mm-dd hh:mm:ss SERVER -> CLIENT: 235 2.7.0 Authentication successful
yyyy-mm-dd hh:mm:ss CLIENT -> SERVER: MAIL FROM:
yyyy-mm-dd hh:mm:ss SERVER -> CLIENT: 250 2.1.0 Ok yyyy-mm-dd hh:mm:ss CLIENT -> SERVER: RCPT TO:
yyyy-mm-dd hh:mm:ss SERVER -> CLIENT: 250 2.1.5 Ok yyyy-mm-dd hh:mm:ss CLIENT -> SERVER: DATA yyyy-mm-dd hh:mm:ss SERVER -> CLIENT: 354 End data with
.
yyyy-mm-dd hh:mm:ss CLIENT -> SERVER: Date: Wed, 21 Aug 2024 07:54:44 +0000 yyyy-mm-dd hh:mm:ss CLIENT -> SERVER: To: TO_ADD yyyy-mm-dd hh:mm:ss CLIENT -> SERVER: From: headerfrom Name
<headerfrom@xxxxxx.com>
yyyy-mm-dd hh:mm:ss CLIENT -> SERVER: Subject: Test Mail from PHP yyyy-mm-dd hh:mm:ss CLIENT -> SERVER: Message-ID:
<thtoovtkvz3kfmwhvzzk2r9lmi4yf5wmpg55q933upw@your_host>
yyyy-mm-dd hh:mm:ss CLIENT -> SERVER: MIME-Version: 1.0 yyyy-mm-dd hh:mm:ss CLIENT -> SERVER: Content-Type: text/plain; charset=iso-8859-1 yyyy-mm-dd hh:mm:ss CLIENT -> SERVER: yyyy-mm-dd hh:mm:ss CLIENT -> SERVER: PHP yyyy-mm-dd hh:mm:ss CLIENT -> SERVER: yyyy-mm-dd hh:mm:ss CLIENT -> SERVER: . yyyy-mm-dd hh:mm:ss SERVER -> CLIENT: 250 2.0.0 Ok: queued as 231078522F62 yyyy-mm-dd hh:mm:ss CLIENT -> SERVER: QUIT yyyy-mm-dd hh:mm:ss SERVER -> CLIENT: 221 2.0.0 Bye
</thtoovtkvz3kfmwhvzzk2r9lmi4yf5wmpg55q933upw@your_host>
</headerfrom@xxxxxx.com>
今回作成したプログラムではSMTP接続に失敗した場合でもリトライされません。
また、エラー処理も最低限となっておりますので、実際に業務やサービスとして使用される場合は、SMTP接続に失敗した場合のリトライ処理、プログラムの再実行処理、エラー処理やログの生成などのカスタマイズが必要になります。
今回はプログラム単体で実行しましたが、PHPはWebサーバーと一緒に使用することで真価を発揮するプログラミング言語です。WEBページから入力情報を受取り、PHPのプログラムに渡すことで問い合わせフォームとして使う、一定の条件で通知メールを送る、といった用途に応用することが出来ます。
PHPMailerは、シンプルなメール送信から、HTMLメール、添付ファイル、SMTP認証などを必要とする高度なメール送信まで幅広く対応できるため、さまざまな場面で利用されています。
以下に、
$mail->isHTML(true)
$mail->Subject =
$mail->Body =
の3つを編集することで使用できる簡単なサンプルを用意しました。
smtp_config.phpで定義した配信情報を使い回す形としているので、別のサーバーやメールアドレスに変更したい場合はsmtp_config.phpを編集する必要があることに注意して下さい。
Webアプリケーションでユーザー登録を行う際に、確認メールを送信してアカウントの有効化を求めることが一般的です。この場合、PHPMailerを使って以下の機能を実現できます。
<?php
require 'vendor/autoload.php';
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
$config = require 'smtp_config.php';
$to = $argv[1];
$mail = new PHPMailer(true);
try {
$mail->SMTPDebug = 0;
$mail->isSMTP();
$mail->Host = $config['host'];
$mail->SMTPAuth = true;
$mail->Username = $config['username'];
$mail->Password = $config['password'];
if ($config['use_tls']) {
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
} else {
$mail->SMTPSecure = '';
}
$mail->Port = $config['port'];
$mail->setFrom($config['from_email'], $config['from_name']);
$mail->Sender = $config['envelope_from'];
$mail->addAddress($to);
// ここから下を編集することで様々なメールに対応できます。
// --------------------------------------------------------
// HTMLメールを送る場合はtrue
$mail->isHTML(true);
// 目的に応じたメールタイトルを設定
$mail->Subject = 'Confirm your registration';
// bodyにHTMLを記述
$mail->Body = '
<html>
<head>
<style>
table {
border-collapse: collapse;
width: 100%;
}
td, th {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
tr:nth-child(even) {
background-color: #f2f2f2;
}
</style>
</head>
<body>
<table>
<tr>
<td>こんにちは!</td>
</tr>
<tr>
<td>ご登録ありがとうございます。</td>
</tr>
<tr>
<td>下記のリンクをクリックして、ご登録を完了してください。</td>
</tr>
<tr>
<td>
<a href="https://yourwebsite.com/confirm.php?token=' . htmlspecialchars($token, ENT_QUOTES, 'UTF-8') . '">アカウントを有効化する</a>
</td>
</tr>
</table>
</body>
</html>
';
// ---------------------------------------------------------------
$mail->XMailer = ' ';
$mail->send();
echo "Message has been sent to $to
";
} catch (Exception $e) {
echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}
";
}
?>
================================
ユーザーがパスワードを忘れた場合、PHPMailerを利用してパスワードリセットのリンクを送信することができます。この場合、セキュリティ上の理由から、リンクには短時間で失効するトークンが含まれます。
// テキストメールとして送信
$mail->isHTML(false);
$mail->Subject = 'Password Reset Request';
$mail->Body = "Hello,
We received a request to reset your password. Please use the following link to reset it:
" .
"https://yourwebsite.com/reset.php?token=" . urlencode($resetToken) . "
" .
"If you did not request this, please ignore this email.
Best regards,
Your Website Team";
今回は、PHPのメール送信ライブラリであるPHPMailerを使って、シンプルなメール送信プログラムを作成しました。PHPMailerは、入門者でも比較的容易に扱えるため、メール送信機能を実装したいと考えている方にお勧めです。
今回紹介したプログラムは必要最低限の機能しか持たせていませんが、実際の開発現場では、エラー処理、添付ファイルの対応など、より高度な機能が必要となる場合があります。
SwiftMailer は開発が終了してしまっていますが、PHPMailerの他にもSymfonyなど、様々なメール送信ライブラリやフレームワークが存在しますので、開発規模や要件に合わせて、最適なライブラリを選ぶことが重要です。本記事が参考になれば幸いです。