PHPMailerを使ってメール送信
以前、Composerをインストールしました。その目的は、Debianで稼働しているSMTPサーバーにOSからメールメッセージを渡したかったからです。
ここではPHPMailerというパッケージを使って、SMTP認証を含めてそれを実現する方法を書いていきます。
ちなみに、PHPでなくJavaからメールを送る方法も別記事にて紹介しておりますので、よろしかったら合わせてご覧いただければと思います。
PHPMailerのインストール
後でGitHub:PHPMailerのREADME.mdを読んだら、Composerを使わなくても利用できることが判明しましたが、とりあえずComposerありでインストールします。
メール用のPHPのディレクトリ(プロジェクト)を作成しそこで、composer require を実行します。Composerはユーザー権限で実行する必要があります。
phpファイル記述
PHPMailerをインストールしたフォルダ、vendorやcomopser.lockがある階層にPHPファイルを作成します。そこからPHPMailerライブラリを指定して利用します。メール送信用の関数には、引数に送信先メールアドレスと、タイトル、本文を持たせ、あとの必要な情報は定数としてファイル内に記述します。
ポート25番で暗号化なしのSMTP認証を使う例
<?php
//名前空間を使ってクラスをインポートしています。
//環境によって円マークはバックスラッシュになります。
use PHPMailer¥PHPMailer¥PHPMailer;
use PHPMailer¥PHPMailer¥Exception;
//use PHPMailer¥PHPMailer¥SMTP;
//composerが作成するファイルを使って必要なファイルをロードします。
require 'vendor/autoload.php';
//composerを使っていない場合は次のファイルをロードします。
//require 'path/to/PHPMailer/src/Exception.php';
//require 'path/to/PHPMailer/src/PHPMailer.php';
//require 'path/to/PHPMailer/src/SMTP.php';
//環境設定です。
define('MAIL_SENDER_ADDRESS','no-reply@sample.jp');//メール送信者のアドレス
define('MAIL_SENDER_NAME','information');//メール送信者の名前
define('SMTP_SERVER','127.0.0.1');//SMTPサーバー
define('SMTP_USER','smtp_user');//SMTPユーザー名
define('SMTP_PASS','smtp_pass');//SMTPパスワード
//コマンドラインで実行し次の引数が入っているものとしています。
//1.宛先 2.タイトル 3.本文
if(php_sendmail($argv[1],$argv[2],$argv[3])){
//送信成功
exit(0);
}else{
//送信失敗
exit(1);
}
function php_sendmail($strTo,$strTitle,$strMsg){
mb_language("japanese");
mb_internal_encoding("UTF-8");
$mailer=newPHPMailer();
try{
//$mailer->SMTPDebug=SMTP::DEBUG_SERVER;//定数DEBUG_SERVERを利用するためには、SMTPクラスのインポートが必要です。
$mailer->IsSMTP();//SMTP
$mailer->Host=SMTP_SERVER;//SMTPサーバーのアドレス
$mailer->SMTPAuth=true;//SMTP認証の設定
$mailer->Username=SMTP_USER;//ユーザー名
$mailer->Password=SMTP_PASS;//パスワード
//$mailer->SMTPSecure='';//STARTTLSならPHPMailer::ENCRYPTION_STARTTLS、SSLならPHPMailer::ENCRYPTION_SMTPSとします。
$mailer->Port=25;//ポート番号
//送信メールの設定
$mailer->CharSet='utf-8';//メッセージのエンコードを指定
$mailer->setFrom(MAIL_SENDER_ADDRESS,MAIL_SENDER_NAME);//送信者のアドレスと名前
$mailer->addAddress($strTo,'');//受信者のアドレスと名前
//$mailer->addReplyTo('replyto@example.com','Replyto');
//$mailer->addCC('cc@example.com');
//$mailer->addBCC('bcc@example.com');
//送信メールの本文
//mb_convert_encodingを使って文字コードが指定したutf-8になるようにしています。
$mailer->isHTML(true);//HTML形式のメールに
$mailer->Subject=mb_convert_encoding($strTitle,"utf-8","auto");
//HTMLなので、bタグ等が利用可能です。
$mailer->Body=mb_convert_encoding($strMsg,"utf-8","auto");
//送信実行
$mailer->send();
return true;
}catch(Exception $e){
//エラー
return false;
}
}
?>
ポート587番でSTARTLSを使ってSMTP認証をし、ログ出力する例
<?php
//名前空間を使ってクラスをインポートしています。
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
//composerが作成するファイルを使って必要なファイルをロードします。
require 'vendor/autoload.php';
//コマンドラインで実行し次の引数が入っているものとしています。
//1.宛先 2.タイトル 3.本文
if(php_sendmail($argv[1],$argv[2],$argv[3])){
//送信成功
exit(0);
}else{
//送信失敗
exit(1);
}
function php_sendmail($strTo, $strTitle, $strMsg) {
mb_language("japanese");
mb_internal_encoding("UTF-8");
$mailer = new PHPMailer();
try {
//ログ出力と、保存の設定
$mailer->SMTPDebug =2; //SMTP::DEBUG_SERVER定数を利用するならSMTPクラスのインポートが必要です。
$mailer->Debugoutput = function($str, $level) { file_put_contents("phpmailer.log",$str); };
$mailer->IsSMTP();
$mailer->Host = "MAIL.SERVER";//SMTPサーバードメインかアドレス
$mailer->SMTPAuth = true;//SMTP認証の設定
$mailer->Username = "SMTP_USER"; //ユーザー名
$mailer->Password = "SMTP_PASS"; //パスワード
$mailer->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;//STARTTLS SSLならPHPMailer::ENCRYPTION_SMTPSとします。
$mailer->Port = 587;//ポート番号
$mailer->CharSet = 'utf-8';//メッセージのエンコードを指定
$mailer->setFrom("MAIL_SENDER_ADDRESS", "MAIL_SENDER_NAME"); //送信者のアドレスと名前
$mailer->addAddress($strTo, '');//受信者のアドレスと名前
//本文
//mb_convert_encodingを使って文字コードが指定したutf-8になるようにしています。
$mailer->isHTML(true);//HTML形式のメールに
$mailer->Subject = mb_convert_encoding($strTitle,"utf-8","auto");
//HTMLなので、bタグ等が利用可能です。
$mailer->Body = mb_convert_encoding($strMsg,"utf-8","auto");
return $mailer->send();//送信実行
} catch(Exception $e) {
//エラー
file_put_contents("phpmailer.log",$e->getMessage());
return false;
}
}
?>
STARTTLS利用時のトラブル
筆者はさくらインターネトのレンタルサーバーでメールサーバーを利用させてもらっているのですが、このサーバーとSTARTTLSを使った認証時にハマったことがありました。
それはQuiita:「さくらのメールボックスを PHPMailer で SMTP + STARTTLS で送信する時の注意点」を参考にさせていただき解決しました。ありがとうございました。
筆者の環境ではDNSのCNAMEレコードを使って、とあるドメインのメールを先のさくらのレンタルサーバーのドメインに変換していたのですが、この設定だと認証が正しくできません。
おそらくCNAME前のアドレスで証明書の内容を検証しているのだと思います。CNAMEで変換する本来のメールサーバーのドメインにすることで、接続することができました。たぶん「さくら」でなくてもエラーがでるのではないでしょうか?
また、PHPMailerではDKIMの設定も可能です。設定方法に関しては別記事で紹介していますのでよろしければご確認ください。