エス技研

WordPress、CakePHP、PHP、baserCMSなどの Web系システムを中心に情報を提供します!


Phpmailerでスパム回避!Gmail等のSMTPを経由するPHPのメールフォーム解説

      2017/06/04

PHPから Phpmailerを使ってメールを送信

 
PHPでメールを送信する関数と言えば、mail関数や、mb_send_mail関数がありますが、この関数を使うと Yahooや Gmail宛のメールがスパム判定されてしまう...
 
そんな困った状況でもメールを送信できてしまう PHPのライブラリを紹介します。
関数化してますので、コピペで OK!
 
 
そもそも借りているサーバにメールサーバが用意されていなくて、メールが送信できない...
そんな場合でも対応できます。
 
ちなみに、パソコンに XAMPPを入れてローカル環境を作っている場合でも OKです。
ただ、そもそも XAMPP環境でメールを送信できるようにしたいという場合は、後述の「Phpmailerでローカル環境からもメール送信」を参照してください。
 
 

mb_send_mailで送信するとスパムと判定

 
そもそも、なぜ mail関数や、mb_send_mail関数ではスパム判定されてしまうのでしょうか?
 
他のサイトでは「ヘッダー要素が不足しているので引数で指定する要素を追加して見ましょう」といった感じで PHPの記述の内容を変えることで対応できるようなことが書かれています。
ですが、mail関数や、mb_send_mail関数は、メールを送信するプログラムである sendmailを通してメールを送信するのですが、この sendmailのメールサーバとしての設定が正しくない場合は、スパムとして判定されてしまうのです。
 
そのため、いくら PHPの記述方法を変更してもスパムとして判定される根本解決にはならないのです。
 
 

スパム判定されないための解決策

 
20150603_web_01
 
メールの送信の処理をイメージにまとめたものが上記のものになります。
 
1.は、mail関数や、mb_send_mail関数を使って送信する場合です。
PHPで、メールのヘッダ、送信先、タイトル、本文などを編集し、mb_send_mail関数を使って、sendmailにメールを送信してもらいます。
これが前項で説明した内容です。
 
 
2.は、この記事で解説をするライブラリ「Phpmailer」を使って送信する場合です。
PHPで、メールのヘッダや本文などを編集するところまでは同じですが、同じサーバ内の sendmailに渡すのではなく、外部の SMTPサーバに接続し、そこからメールを送信してもらう方法です。
 
外部のメールサーバは、Gmailのサーバだったり、自分で契約しているプロバイダやレンタルサーバの SMTPサーバを利用します。
こうすることにより、送ったメールはスパムとして判定されなくなります。
 
この外部の SMTPサーバを経由してメールを送信するためのライブラリが「Phpmailer」なのです。
このライブラリは、XOOPSという CMSや Symfonyという PHPフレームワークなどでも採用されているライブラリですので、信頼できるものです。
 
 
ちなみに、この方法は、パソコンから Outlookなどのメールソフトを使ってメールを送っていることと同じことをやっているわけですので、これでスパム判定された場合は、Outlookを使って送信してもスパム判定される SMTPサーバだということになります。
 
 


 

Phpmailerを使って Gmailの SMTPからメール送信

 

Phpmailerを設置

 
まずは、Phpmailerを設置します。
 
 http://phpmailer.worxware.com/
オフィシャルサイトは上記ですが、ソースは Githubからダウンロードします。
 
20150603_web_02
 
下記がその Githubの画面です。
 
 https://github.com/Synchro/PHPMailer
 
20150603_web_03
 
Githubを使ったことがない方は分かりにくいですが、右ナビの下に「Download ZIP」というボタンがありますので、それをクリックします。
Githubはプログラムなどのファイルを保存管理(履歴管理)しておくための仕組みです。
 
ダウンロードしたファイルを解凍して、フォームを作成しているフォルダなどに入れます。
フォルダ名も適当に変更しても問題ありません。
 
この記事では「PHPMailer」というフォルダ名に変更して、PHPのプログラムが置いてあるフォルダと同じ階層に置いた想定で記述しています。
 
また、下記のフォルダとその中身のファイルは要らないので消しても OKです。
他にもいらないものはありそうですが...
 docs
 examples
 test
 
 
※2015.07.06 追記
ここで紹介しているフォームからメールを送信するだけであれば、下記の 3ファイルだけあれば動くようです。
 class.phpmailer.php
 class.smtp.php
 PHPMailerAutoload.php
 
 

Phpmailerを利用する PHPのソース

 

Phpmailerの読み込みと SMTP設定

 
Phpmailerを読み込む設定と、メールを送信する SMTPサーバの情報を指定します。
プログラムの設定ファイルか、プログラムファイルの先頭に記述しておけばいいでしょう。
 

 
 

メールの送信の関数と関数を呼び出す設定

 
下記が実際にメールを送信する処理です。
phpmailersend関数の引数となる各値は、あらかじめ定数として設定をしておくか、フォームからの入力値などを編集して設定してください。
 

 
 

Phpmailerを利用する PHPのソースの解説

 
上記で設定したソースの解説を行います。
動けばいいという場合は、読み飛ばしてもらって構いません。
 
 

Phpmailerの読み込み(2行目)

 
require_once ( './PHPMailer/PHPMailerAutoload.php' );
の部分ですが、他のサイトでは下記の様に記載してあるサイトも多々ありました。
 
require_once ( './PHPMailer/class.phpmailer.php' );
 
ですが、私の環境では後者の設定では下記のエラーが出てうまく動きませんでしたので、前者の設定に切り替えました。
同じようなエラーが出る場合は切り替えてみてください。
PHP Fatal error: Class 'SMTP' not found in ./lib/phpmailer/class.phpmailer.php
 
正確な情報は不明ですが、Phpmailerのバージョンによって設定の仕方が違う可能性があります。(今回のこの解説は Phpmailer Ver. 5.2.9で行っています。)
 
 
ちなみに「require_once」の部分は、「require」「include_once」「include」でも何の問題もありません。
 
 

SMTPサーバの設定(4行目~)

 
「外部SMTPサーバーのホスト名」は、Gmailの場合は「ssl://smtp.gmail.com」「tls://smtp.gmail.com」を設定します。
レンタルサーバやプロバイダなどの契約しているメールサーバを使用する場合は、PCのメールソフトに設定している SMTPサーバを設定します。
 
「外部SMTPのポート番号」は、Gmailの場合は「465」を指定します。
一般的には「587」となっていますので、契約しているメールサーバの場合は「587」を使うことになるでしょう。
 
「外部SMTPに接続するユーザー名」は、Gmailの場合は「username@gmail.com」になります。
レンタルサーバの場合は、「username@hogehoge.com」の様にメールアドレス全体の時と、「username」の部分だけの場合とありますので、確認してから設定してください。
 
「外部SMTPに接続するパスワード」は、パスワードを指定します。
ただし、Gmailの場合は、パスワードを指定しただけでは「Mailer Error: SMTP connect() failed.」のエラーとなる場合がありますので、注意してください。
詳細は後述の「Gmailのパスワードの設定について」に書いていますので参考にしてみてください。
 
 

Phpmailerの実行関数(16行目~18行目)

 
関数に与える「$to」「$ccadress」「$bccadress」の値は下記の様に、「,(カンマ)」で複数の設定も想定しています。
そのため、スペースを削除した上でカンマで区切って配列に入れる処理になっています。
 
$to = "aaa@hogehoge.com, bbb@hogehoge.com, ccc@hogehoge.com";
 
処理上はスペースが混ざっているメールアドレスを Phpmailerに与えても問題ありませんでしたね。
スペースを省く処理くらいは Phpmailerでもやっているようです。
 
 
ちなみに、ここで配列に入れたものを 34行目~42行目の「foreach」で入力されている数だけ設定を追加していきます。
 
 

Phpmailerの実行関数(22行目~23行目)

 
22行目、23行目の「CharSet」と「Encoding」の設定は、記述しなくてもメール送信は可能です。
ただ、文字化けをする場合はこれを指定するといいでしょう。
 
 


 

Phpmailerが利用できる条件・PHPのバージョン

 
Phpmailerの解説の中で明確な条件を確認することはできていませんが、このライブラリは PHP 4系では利用することはできません。
 
理由は、ライブラリを呼び出す際に「$mailer = new PHPMailer();」と記述するオブジェクト関連の処理が PHP4系では実装されていないためです。
 
たぶん、PHP5.0以降では利用できると思いますが、実際に試してみた一番古いバージョンとして PHP 5.2.17では OKだった、という感じです。もちろん、それ以降のバージョンは OKでした。
また、4.4.9以前のバージョンでは NGでした。
 
 
 

Gmailのパスワードの設定について

 
Gmailのパスワードに限らず、Googleのサービスは ID、PASSを厳密に管理するようになってきています。
そのため、Gmailがデフォルトの設定のままでは直接 SMTPサーバにアクセスできないようになっています。
一般的にメールを送受信する際にも、メールソフトによっては Gmailのメールを扱えないものもありますが、それはこの設定によるものです。
 
Gmail関連でメールの設定に関しては、下記のサイトに説明がありますので参考にしてみてください。
 http://www.atmarkit.co.jp/ait/articles/1409/03/news109.html
 
 
で、契約しているプロバイダの SMTPサーバだと問題ないのに、Gmailに変えると下記のエラーメッセージが表示されるという場合は、Gmailの設定を変更してみてください。
Mailer Error: SMTP connect() failed.
 
下記 URLの Googleアカウント設定にアクセスをします。
 https://myaccount.google.com/?pli=1
 
20150603_web_04
 
20150603_web_05
 
上記のある「安全性の低いアプリのアクセス」を「オンにする」にすることで「許可」に変更することができます。
これで設定している内容でアクセスが可能になります。
 
 

Phpmailerでメール送信時の注意点

 
TOと CC、TOと BCCのアドレスが同じ場合は TOにしか送信されませんので注意が必要です。
 
これは Phpmailerでメールを送信するプログラムの時だけの注意点ではありませんが、結構忘れがちの落とし穴ですので、「なんで 1通しかメールが届かないの?」という不具合の時にはチェックしてみてください。
 
 
 

Phpmailerでローカル環境からもメール送信

 
XAMPPなどのローカル環境を構築して、プログラムの勉強やシステム開発を行っている方もいらっしゃると思いますが、ローカル環境なのでメール送信の環境がなくて困っている!という場合も、この Phpmailerライブラリを使うことでメールを送信することができてしまいます。
 
 
もっとも、そもそも XAMPP環境からメールが送信できないとメールフォームだけではなく、WordPressで何か開発する際なども困るわけですので、そんな場合は「ローカル環境の XAMPPからメールを送信できるように設定する」という記事を書いていますが、この記事の内容の対応をすることで XAMPP環境からもメールが送信できるようになります。
結局は、Gmailのメールサーバにメールを送ってもらっているわけですが。
 
 

Phpmailerと同種の Qdmailを使う場合

 
Phpmailerと同じように、PHPから外部の SMTPサーバを経由してメールを送信する機能を提供するライブラリとして、「Qdmail」「Qdsmtp」というものがあります。
 
私は Phpmailerより先にこれを見つけたために、これを先に使ってみたワケですが、開発がずいぶん前に止まってしまったようで、現在の PHP5などでは下記の様にエラーが出てしまいます。
 

 
 
これは、PHPのエラーレベルに「E_DEPRECATED」が加わったことで出るもので、将来的にサポートされなくなる関数が使われているときに出る警告です。
現状では警告メッセージが出るだけですので、使用するプログラムに下記のエラーメッセージの制御コードを追加すれば見えなくなります。
 

 
もしくは、.htaccessに書く場合は下記を指定します。
 

 
 
これで警告メッセージは見えなくなりますし、現時点ではプログラムの動作も何の問題もありませんが、将来的にはサポートされなくなる関数が入っているわけですし、積極的にこちらの Qdmailを使う理由が見当たりません。
 
Phpmailerはファイル数、ファイル容量が大きいためにその点が問題になる場合があれば、Qdmailを使う場面もある可能性はゼロではありませんが、実際ありえないでしょうね。
 
 
今後もスパム判定が厳しくなることはあってもゆるくなることは考えられませんので、今のうちから Phpmailerを利用しておくといいでしょうね。
 
 

WordPressで Phpmailerを利用する場合

 
ここで紹介したメールを送信するとスパム判定されてしまう問題点は WordPressにも同様に存在します。
ですが、WordPressの場合は、WP Mail SMTP、WP SMTP、Easy WP SMTPといったプラグインで簡単に対応が出来てしまいます。
その解説の記事を下記に書いていますので、あわせて参考にしてください。
WP Mail SMTP、WP SMTP、Easy WP SMTPでWordPressのメールのスパム判定を回避
WP Mail SMTPはPHP5.6、7.0系ではメール送信時にエラーが発生。その対処方法。
SMTP Mailerでスパム判定回避。WP Mail SMTPで発生する送信エラーも対応

 - PHP・Smarty・ECCUBE

GoogleAdwords

GoogleAdwords

最後までお読みいただきましてありがとうございます。
この記事が参考になったと思いましたらソーシャルメディアで共有していただけると嬉しいです!

Comment

  1. sounisi5011 より:

    PHPMailerのダウンロードページとして提示しているGithubですが、正しくは https://github.com/PHPMailer/PHPMailer です。
    (以下、上記のリンク先をPHPMailer/PHPMailerとします)

    紹介しているページの上をよく見ると分かるのですが、「forked from PHPMailer/PHPMailer」とあります。
    これは、PHPMailer/PHPMailerをコピーした、のような意味合いで、本来のページがPHPMailer/PHPMailerであることを示しています。
    また、commitsの数(更新数)も、PHPMailer/PHPMailerのほうが多いことがわかると思います。

    • エス技研 より:

      sounisi5011さん、コメントありがとうございます。
      理解不足でご迷惑をおかけしました。
      近日中に記事の方も更新をさせていただきます!

Message

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

下記の空欄を埋めてください。 * Time limit is exhausted. Please reload CAPTCHA.

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

※入力いただいたコメントは管理者の承認後に掲載されます。

  関連記事

PHPで特定の日間の日付を for、strtotimeで表示する

ある特定の間の日付の情報を for文、strtotimeを使って作成し、その解説をしています。

路線・駅検索をPHPで実装する方法解説。GoogleMapsの緯度経度から計算し検索
路線・駅検索をPHPで実装する方法解説。GoogleMapsの緯度経度から計算し検索

路線・駅検索の仕組みの構築は大変。登録する側も最寄り駅が多い場合は大変。なので簡易に実装するため緯度経度に基づき直線距離を計算する処理を考案して実装して、その処理を解説。

ECCUBEの商品一覧ページのSEO対策!rel=”next” rel=”prev”を設定

Googleは関連あるページはその旨明示するよう求めています。ECCUBEの商品一覧ページでその求めに応じるための「rel=”next”」「rel=”prev”」について解説します。

ECCUBEでアップロードできない。upload_max_filesizeを設定する場所

テンプレートをアップロードする際に発生するエラー「テンプレートファイルがアップロードされていません」の対処方法。これはファイル容量の制限に引っかかっています。

ファイル変更だけ!ECCUBEの本番から開発環境をコピーする手順を解説

ECCUBEを本番から開発環境をコピーする際の手順を解説。PGMメンテに必要な開発環境を構築する手順を解説。ECCUBEの仕組みは簡単なので作業は5分ほど。

PHP画面が真っ白 header(“Location: $url”);

PHPの開発で header(“Location: $url”);を使うと画面が真っ白になる不具合が出る場合もあります。

ECCUBEでカード決済NGの受注情報をマイページ購入履歴に表示しない方法解説

ECCUBEでカード決済に失敗しても購入履歴一覧に注文情報(受注情報)が表示される問題への対処方法を解説。受注情報レコードの作成の流れとステイタスについても解説。

Smartyの修飾子regex_replaceで正規表現の後方参照・PHPではpreg_replace

ECCUBEで使われているSmartyで文字列を正規表現で置換し後方参照で値を利用する装飾子regex_replaceの解説です。細かな条件がありますので注意が必要です。

Basic認証の.htaccess、.htpasswd生成ツールと解説

Basic認証を設定する際に必要となる.htaccess、.htpasswdファイルを生成するツール。ID、PASS、.htpasswdへのパスを入力することで編集する情報を生成します。

ECCUBE2.13.3で商品規格の在庫数が無制限から変更できないバグがある

2.13.3固有のバグである商品規格の在庫数の入力エリアがアクティブにならない不具合を解消する解説です。product_class.tplの2行を修正するだけの簡単対応です。