質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
Sendmail

Sendmailは、インターネットで電子メールを送受信するサーバソフトウェア(MTA)です。ユーザーが送信したメールを受け、他メールサーバへ引き渡しバケツリレー式に配送したり、届いたメールをユーザーが受け取るまでの間保管するといった働きをします。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

1回答

564閲覧

PHPMailerを使用したメール送信が不安定。

BreadMan

総合スコア2

Sendmail

Sendmailは、インターネットで電子メールを送受信するサーバソフトウェア(MTA)です。ユーザーが送信したメールを受け、他メールサーバへ引き渡しバケツリレー式に配送したり、届いたメールをユーザーが受け取るまでの間保管するといった働きをします。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

3クリップ

投稿2024/07/25 08:58

編集2024/07/26 10:21

teratail初登校です。
粗があったらすみません。

過去の質問
https://teratail.com/questions/191810

この質問を見て、だいたい質問内容が被っているのですが、
望んだ解決方法が記載されていなかったので。

実現したいこと

HPのフォームに入力があったときに以下2つのメールを送信する。
1.入力されたメールアドレスに対しての自動返信メール
2.フォーム管理者メールアドレスへのフォーム内容のメール

環境

サーバー Kusanagi9 nginx122
PHP 7.4.33
PHPMailer 6.9.1
メールサーバー Conoha

コード

メール送信コードは以下です。(抜粋)
(send.php)

php

1 2<?php 3session_start(); 4?> 5 6<HPのヘッダーメニュー>(省略) 7 8<?php 9 //------------------------------ 10 //PHPMailerをインポート 11 //------------------------------ 12 use PHPMailer\PHPMailer\PHPMailer; 13 use PHPMailer\PHPMailer\SMTP; 14 use PHPMailer\PHPMailer\Exception; 15 16 //Composerのオートローダー読み込み 17 require __DIR__ . '/vendor/autoload.php'; 18 //エラーメッセージ用日本語ファイル読み込み 19 require __DIR__ . '/vendor/phpmailer/phpmailer/language/phpmailer.lang-ja.php'; 20 21 //------------------------------ 22 //言語・文字コードの設定 23 //------------------------------ 24 mb_language("japanese"); 25 mb_internal_encoding("UTF-8"); 26 27 //フォーム内容 28 $namae = $_SESSION['namae']; 29 $tenmei = $_SESSION['tenmei']; 30 $email = $_SESSION['email']; 31 $genre = $_SESSION['genre']; 32 $radio = $_SESSION['radio']; 33 $message = $_SESSION["message"]; 34 $current = time(); 35 date_default_timezone_set("Asia/Tokyo") ; 36 $time = date("Y年m月d日 H時i分", $current) ; 37 38 //env.phpの環境変数っぽいphp読み込み 39 $env = require __DIR__ . '/env.php'; 40 41 $smtp_host=$env['smtp_host']; 42 $smtp_from=$env['smtp_from_address']; 43 $smtp_password=$env['smtp_password']; 44 $smtp_port=$env['smtp_port']; 45 $smtp_admin=$env['smtp_admin_address']; 46 47 //------------------------------ 48 //メール本文の整形 49 //------------------------------ 50 $body = 'お問い合わせ日時 : '.$time ."\r\n"; 51 $body .= 'メールアドレス : '.$email ."\r\n"; 52 $body .= 'お問い合わせ内容 : '.$message; 53//他情報は記載省略 54 55 //メールインスタンス生成(引数trueでException有効化) 56 $user_mail = new PHPMailer(true); 57 //日本語設定 58 $user_mail->CharSet ='UTF-8'; 59 60//mailerのデバッグ 61 // $user_mail->SMTPDebug=3; 62 63//設定変更 64 $user_mail->SMTPOptions=[ 65 'ssl'=>[ 66 'verify_peer' => false, 67 'verify_peer_name' => false, 68 'allow_self_signed' => true 69 ] 70 ]; 71 72 // SMTPサーバの設定 73 $user_mail->isSMTP(); 74 $user_mail->Host = $smtp_host; 75 $user_mail->SMTPAuth = true; // SMTP authenticationを有効化 76 $user_mail->Username = $smtp_from;// SMTPサーバーのユーザ名 77 $user_mail->Password = $smtp_password; // SMTPサーバーのパスワード 78 $user_mail->SMTPSecure = 'ssl'; // 暗号化を有効(tls or ssl)無効の場合はfalse 79 $user_mail->Port = $smtp_port; // TCPポートを指定(tlsの場合は465や587) 80 81 //送信情報設定 82 $user_mail->setFrom($smtp_from); // 送信者 83 $user_mail->addAddress($email); // 宛先 84 $user_mail->addCC($smtp_from); // CC宛先 85 $user_mail->Sender = $smtp_from; // Return-path 86 87 // 送信内容設定 88 $user_mail->Subject = "お問い合わせありがとうございました"; 89 $user_mail->Body = $body; 90 91 $user_mail->send(); 92 93$_SESSION = array(); 94session_destroy(); 95?> 96<HPのフッター>(省略)

また、フォーム部分については以下のコードです。
(contact.php)

PHP

1<?php 2session_start(); 3$namae = isset($_SESSION["namae"]) ? $_SESSION["namae"] : ""; 4$tenmei = isset($_SESSION["tenmei"]) ? $_SESSION["tenmei"] : ""; 5$email = isset($_SESSION["email"]) ? $_SESSION["email"] : ""; 6$genre = isset($_SESSION["genre"]) ? $_SESSION["genre"] : ""; 7$radio = isset($_SESSION["radio"]) ? $_SESSION["radio"] : ""; 8$message = isset($_SESSION["message"]) ? $_SESSION["message"] : ""; 9?> 10 11<HPのヘッダーメニュー>(省略) 12 13 <form action="./contactphp.php" method="post"> 14 <dl class="form_area"> 15 <dt class="repuired">お名前</dt> 16 <dd><input type="text" name="namae" required value="<?php echo $namae; ?>"></dd> 17 <dt class="repuired">メールアドレス</dt> 18 <dd><input type="email" name="email" required value="<?php echo $email; ?>"></dd> 19(以下フォーム内容省略) 20 </dl> 21 <p class="kakunin">お間違いがなければ[送信]ボタンを押してください。</p> 22 <input type="submit" value="送 信" class="btn"> 23 </form> 24<HPのフッター>(省略) 25

(contactphp.php)

php

1<?php 2session_start(); 3?> 4 5<HPのヘッダーメニュー>(省略) 6 7 <?php 8 9 $namae = htmlspecialchars($_POST["namae"],ENT_QUOTES); 10 $tenmei = htmlspecialchars($_POST["tenmei"],ENT_QUOTES); 11 $email = htmlspecialchars($_POST["email"],ENT_QUOTES); 12 $genre = htmlspecialchars($_POST["genre"],ENT_QUOTES); 13 $radio = htmlspecialchars($_POST["radio"],ENT_QUOTES); 14 $message = htmlspecialchars($_POST["message"],ENT_QUOTES); 15 $message_view = nl2br($message); 16 17 // 入力内容のチェック 18 // 名前のチェック 19 if(strlen(trim($namae)) == 0) {//ゼロバイト(何も入力されていなかったら) 20 $error[] = "名前をご入力ください"; 21 } 22 //メールアドレスのチェック 23 if(strlen(trim($email)) == 0){//ゼロバイト(何も入力されていなかったら) 24 $error[] = "メールアドレスをご入力ください。"; 25 } 26 else{//入っていたとしても下記の形式とマッチしていなかったら"メールの形式が正しくないと表示される" 27 if(!preg_match("/^[a-zA-Z0-9.!#$%&'*+\/=?^_'{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9]+)+$/",$email)){ 28 $error[]="メールの形式が正しくありません。"; 29 } 30 } 31 32 //エラー表示を出すコード 33 if(isset($error)){//エラーを表示させてほしい 34 echo "<ul>\n";//Ulで 35 36 foreach($error as $e) {//エラーを$eとして 37 echo "<li>{$e}</li>\n"; 38 } 39 echo "</ul>\n"; 40 } 41 42 43 echo <<< END 44 45 <table> 46 <tr><th>お名前</th><td>{$namae}</td></tr> 47 <tr><th>メールアドレス</th><td>{$email}</td></tr> 48 <tr><th>お問い合わせ内容</th><td>{$message_view}</td></tr> 49(他省略) 50 </table> 51 52 END; 53 54 ?> 55 56 <a href="./contact.php" class="php_btn">戻る</a> 57 <?php 58 59 if(!isset($error)){//エラーがなければこのボタンを表示させる 60 echo " <a href=\"./send.php\" class=\"php_btn\">送信する</a>\n "; 61 } 62 63 ?> 64<HPのフッター>(省略) 65

質問内容

上記コードでメールの送受信を行った場合、エラーログには何も残りませんでした。
ですが、Outlook(POP3)でのメールを確認したところ、連続したテストの場合最初の1回だけしか受信できませんでした。
フォームのテスト時には、入力欄に同じメールアドレスを入れています。

現段階で、自分としては以下の2通りの原因と考えています。
原因1.自分が理解できていない何かしらのミス。
原因2.同一アドレスから同一アドレスへの連続したメールなのでメールサーバーでスパムとして弾かれている?

質問1
有識者の方々にもっと良い方法などがあれば、アドバイス・ご指摘を受けたいです。
(使っているパッケージからコードから何でも)

質問2
上記の原因2の場合、
実現したいこと2.フォーム管理者メールアドレスへのフォーム内容のメール
についての実現方法をどうしたらよいか。
フォーム管理者メールと送信元メールは常に固定なので、頻発すると困る。
(最悪フォーム入力者へのbccに管理者アドレスを入れるのでもよいが、管理者アドレスはできるだけ不特定アドレスからのメールを受信したくないです)

以上、お知恵を拝借したいです。
よろしくお願いします。

[07/26] 追記

わかっていること
・lolipopサーバー(開発者個人契約)では正常に動作した

新たにわかったこと
・ローカル環境(xampp)で試した結果、
php7.4.33(本番環境),php8.1.12(最新環境)のどちらでも正常に動作した。

・$user_mail->SMTPDebug=3; を有効にした上で、フォームを開いたウィンドウを3つ用意し、
aboutmy.emailのアドレス3つに対して順番に送信テストを行ったところ、
本番環境では出力された結果の3つとも、
CLIENT -> SERVER: RCPT TO:(1つ目のメールアドレス)
となっていた。
対して、xamppのローカル環境で実行したところ、
各ウィンドウとも正常な動作をした。
(ブラウザはChromeで、ウィンドウはそれぞれ別プロファイルを使用)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2024/07/25 09:01

Conohaのメールサーバは、「メールサーバとして」借りているのですか?それとも、「VPSなど」を借りて自分でメールサーバを立てたのでしょうか?
BreadMan

2024/07/25 09:10

ConoHaVPSでドメインを契約した上で、ConoHaメールサーバーを借り、同ドメインで利用しています。 自分でメールサーバーを立ててはいないです。
AbeTakashi

2024/07/25 10:14 編集

> 原因2.同一アドレスから同一アドレスへの連続したメールなのでメールサーバーでスパムとして弾かれている? 十分にありえると思うので、outlook以外のメールアドレス宛(例えばGmail)でもテストすべきかと思います。Gmailの迷惑メールフォルダに入っているようであれば可能性は高そうです(outlookはスパムに厳しい気がしますので)。 ついでにGmailのメッセージのソースを確認して、SPFやDMARCの欄がPASSになってるかを確認してみてください。PASSになってない場合は設定漏れがあるかもしれません。 参考 https://support.conoha.jp/w/spfdkim/ https://qiita.com/ma7ma7pipipi/items/07dbbf31b68cc67658df
BreadMan

2024/07/26 00:17 編集

ありがとうございます。 DMARCの設定は、ドメインのTXTレコードにv=DMARC1; p=noneを設定していました。 (現在はお貼りいただいたqiitaを参考に追加でfo=1; rua=(同一ドメインのメールアドレス)を設定しました。) また、いくつかのGmailアドレス(個人、workspace)宛にメール送信テストを行ったところ、以下のことがわかりました。 ・フォームに同一Gmailアドレスを入力して連続してテストを行っても、メールが最初の1件しか行かない。 ・フォームに別のGmailアドレスを入力して連続してテストを行っても、メールが最初の1件しか行かない。 ・受け取ったメールのソースを確認すると、SPFとDKIMはPASSになっているが、DRAMCの欄はない TXTレコードの設定の変更が反映されるころに再度テストしてみます。
AbeTakashi

2024/07/26 01:38

なるほど、SPFとDKIMはPASSなんですね。この二つがPASSであれば、迷惑メールが原因の可能性は低そうな気がします。DRAMCはそこまで影響がないような気がしますので。受信側よりも送信側でなにかトラブルが起きてそうな気がしてきました。送信コードの手前の処理とか後ろの処理も確認してみた方がいいかもしれませんね。あと、連続でメールを送信する際にメールの件名や文面は変えてますか? どこかの段階で同一メールと判断されて遮断されてる可能性もあるかも、とは思いました。
BreadMan

2024/07/26 01:55 編集

ありがとうございます。 フォームに入力する内容は、メールアドレス以外は毎回変えています。 (タイトル・本文共に test,test2,test3...程度ですが) また、関連部分のコードを追記させていただきました。 基本的にメールの問題が発生するまで全て質問者とは別の者(外部・1名)が開発しており、 また質問者はPHPについては知識がなく、開発者も開発業務初となっています。
AbeTakashi

2024/07/26 03:08

なるほど、なかなかやっかいですね。エラーも出てないということで、とにかくこの手の不具合は切り分けの作業を行っていき、徐々に原因の可能性のある箇所を狭めていくといった方法をとるしかなさそうです。ローカルで問題ないということであれば、Kusanagi9環境のどこかで何かが起きてるという可能性をふまえて、Kusanagi9以外のローカルじゃない環境でテストしてみるとかもありかもしれません(ちょっと大変ですが)。あとはローカル環境とKusanagi9環境の差異がないか?(実はPHPのバージョンが違うとか)もしっかりチェックされると良いかもしれません。
BreadMan

2024/07/26 03:36

なるほど。 開発者からはロリポップのサーバーでは正常に動作していたという報告がありました(のを思い出しました)。 また、これも記載忘れしていましたが、そもそも開発者が使っていたのはPHPMailerではなくmb_send_mailだったのを質問者がPHPMailerを使うように変更したという経緯もあります。 Kusanagi9環境の問題…であるなあらば、(サーバーを変えることはできないので)現状解決方法がない…ということになるでしょうか。 ローカル環境のPHPのバージョンが本番環境より新しいので、これはバージョンを変更して再度テストしたいと思います。
BreadMan

2024/07/26 07:42

(投稿内容にも追記しましたが追記) ローカル環境のPHPのバージョンを最新・本番環境の2種で試しましたが、両方とも正常に動作しました。
Eggpan

2024/07/26 07:48

1.入力されたメールアドレスに対しての自動返信メール これは from: noreply@<自ドメイン>のようなアドレスから、 to: 入力されたアドレスに送信している 2.フォーム管理者メールアドレスへのフォーム内容のメール これは from: noreply@<自ドメイン>のようなアドレスから、 to: 固定の管理者アドレス(自ドメイン)に送信している どちらのメールも1回目だけ届く、2回目以降は迷惑メールなどにも入ってなくて届かない といった状況であってますでしょうか? fromとtoのドメインが同じ自ドメインだとメール配送ルートが変わる場合があるので、そのあたりも変更して試してみると良いかもしれません。
BreadMan

2024/07/26 07:54

はい。1,2ともに合っています。 現象も >どちらのメールも1回目だけ届く、2回目以降は迷惑メールなどにも入ってなくて届かない この通りであっていますが、 現在テスト段階として2のコードは全てコメントアウトしています。 (上記質問のコードに載せていません) よって現在は 1の状態において、1回目だけ届く、2回目以降は迷惑メールなどにも入ってなくて届かない。 となっています。 また、この時の入力されたアドレスが同じでない場合も同様の動作となっています。 (1回目のフォームにアドレスA、2回目フォームにアドレスBでテストをすると、Bには何も届かない)
Eggpan

2024/07/26 08:15

> また、この時の入力されたアドレスが同じでない場合も同様の動作となっています。 これについて、gmailなどのセキュリティが強めのメールアドレスを使っているのであれば、メール内容のテストサービスのアドレスに2回おくってみるというのはどうでしょうか? たとえば下記のような、メールの各種設定に不備がないかを確認するサービスです。 https://aboutmy.email/ このようなサービスは基本的にメールは全部うけて判定するので、2回目の送信自体が正しく行われているのかの切り分けができるかと思います。
BreadMan

2024/07/26 08:32

ありがとうございます。 そちらのサイトで発行されたメールアドレスで試した結果、 本番環境では2回目以降の送信ができていない状態だと思います。 1つ気になったのは、 送信が成功したメールのソースをGmailで見た場合は SPF : PASS DKIM : 'PASS' となっているのに対し、 aboutmy.emailでは Authentication SPF Aligned DKIM Unsigned DMARC missing となっています。
Eggpan

2024/07/26 08:52

毎回違うアドレスが発行されるので、別タブで開くなどして1回目と2回目では違うアドレスで試してみてください。 それで2回目が届いてないのであれば、SPFやDKIMなどでが原因で受信側が拒否しているのではなく、送信メールサーバーが何らかの原因で2回目の配送を拒否している可能性が高いです。 About My Emailは日本語が入ったメールだと正しく処理出来ないことがあったかもしれません。 GmailでPASSしているのであれば、とりあえずは問題ないかと思います。
BreadMan

2024/07/26 10:29 編集

ありがとうございます。 使い方は合っていたようで安心しました。 先ほど コード上の // $user_mail->SMTPDebug=3; を有効にした上で、フォームを開いたウィンドウを3つ用意し、 aboutmy.emailのアドレス3つに対して順番に送信テストを行ったところ、 本番環境では出力された結果の3つとも、 CLIENT -> SERVER: RCPT TO:(1つ目のメールアドレス) となっておりました。 対して、xamppのローカル環境で実行したところ、 各ウィンドウとも正常な動作をしました。 ブラウザはChromeで、ウィンドウはそれぞれ別プロファイルを使用しています。 おそらくセッション関係…?kusanagiかnginxの…? という推測したのですが、知識不足のためそれ以上はわかりません。 これから何かわかることはありますでしょうか。 (このコメントは質問本文にも載せておきます)
BreadMan

2024/07/26 10:34

追記、 この2通目以降のメールが送信できていない間、 同ドメインの別のページ(サブドメイン・Kusanagiで作ったworkdpressページ)内の 問い合わせフォームに入力された内容もメールが送信されていないようです。(開発者からの報告)
Eggpan

2024/07/26 11:45

kusanagiのキャッシュが効いてしまっていているのではないでしょうか? echo " <a href=\"./send.php\" class=\"php_btn\">送信する</a>\n "; の部分を echo " <a href=\"./send.php?" . time() . "\" class=\"php_btn\">送信する</a>\n "; のようにして、URLが毎回かわるようにすると変化ないでしょうか。 fcacheが有効の場合、GETリクエストで同じURLだと10分間のキャッシュが効くようです。 https://www.prime-strategy.co.jp/column/archives/column_7079 もしこれが原因ですと、対処としてはキャッシュを無効化する、URLが変わるようにする、formタグにしてPOSTリクエストにする、あたりになりそうです
BreadMan

2024/07/26 12:13

contantphp.php内を echo " <a href=\"./send.php?" . time() . "\" class=\"php_btn\">送信する</a>\n "; に変更したところ正常に動きました! ありがとうございます! ただ、現在この問題が起きているこのプロジェクトはkusanagiプロファイルではないので (Kusanagiを利用しているのは先述した物を含めた複数の別のWordPressサイトのため) fcacheの有効かを確認する kusanagi fcache statusコマンドを実行するとエラーを吐きます。 (current directory is not KUSANAGI profile) この場合原因はkusanagiのfcacheではない、別のcacheと考えるべきでしょうか。 (だんだん質問内容がphpからズレてしまっていて申し訳ありません。)
Eggpan

2024/07/26 12:24

原因に近いところまでたどり着けたようで、良かったです。 kusanagiに限らず、レンタルサーバーですとキャッシュ・アクセラレーターといったような名前でキャッシュの仕組みがあるところは割とあります。 毎回異なる処理を行う場所についてはPOST送信にすることで解消できることが多いですが、解決しないのであればサーバーのサポートに聞かれたほうが良いかと思います。
BreadMan

2024/07/26 12:55

ありがとうございます。 なんとか自力でできそうな範囲なのでいろいろ試してみます。
BreadMan

2024/07/26 13:01

今回はこれで解決とさせていただきます。 teratail初心者で申し訳ないですが、ベストアンサーは質問とは別に解答として入力していただくようですね。 長いやり取りをまとめていただくことになりますが、よければ解決法としてご回答いただけたら幸いです。
guest

回答1

0

ベストアンサー

(コメントに記載した事の概要を転記)

まずは、メールは送信されているが、受信側で拒否されるなどで届いていない状態なのかの切り分けを行います。
outlookやgmailなどでは迷惑メール判定が厳しく受信できない可能性があるので、 https://aboutmy.email/ 等、メールの検証サービスに対して送信してみる等。
これらのサービスは一度メールを受信した上で迷惑メールリストに載っているかなどの解析結果を出力するので、迷惑メールフィルタによって弾かれるということは基本的にありません。

メール検証サービスを利用して2回目が届かない場合、受信側ではなく送信側に問題が起きている可能性が高いです。
送信メールサーバーにフィルタリングがあって弾かれている、キャッシュなどが効いていてプログラムが動いていないなどです。

送信メールサーバー側の問題ですとメールサーバーを提供しているサービスのサポートに問い合わせるなどになるかと思います。

キャッシュが原因の場合、下記の様な対応が必要となります。

  • POSTリクエストを受けるプログラムは基本的にキャッシュされないので、formタグでPOST送信するようにする
  • URLが異なればキャッシュされないので、 <a href="some_url?' . time() . '">' のようにタイムスタンプを追加するなどして異なるURLとなるようにする
  • サーバー側の設定でキャッシュの動作を変更する

投稿2024/07/28 13:30

Eggpan

総合スコア3203

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

BreadMan

2024/07/30 00:23

ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問