PHP メール関数が電子メールの送信を完了しない 質問する

PHP メール関数が電子メールの送信を完了しない 質問する
<?php
    $name = $_POST['name'];
    $email = $_POST['email'];
    $message = $_POST['message'];
    $from = 'From: yoursite.com';
    $to = '[email protected]';
    $subject = 'Customer Inquiry';
    $body = "From: $name\n E-Mail: $email\n Message:\n $message";

    if ($_POST['submit']) {
        if (mail ($to, $subject, $body, $from)) {
            echo '<p>Your message has been sent!</p>';
        } else {
            echo '<p>Something went wrong, go back and try again!</p>';
        }
    }
?>

簡単なメール フォームを作成してみました。フォーム自体は私のindex.htmlページにありますが、上記の PHP コードが埋め込まれている別の「送信ありがとうございます」ページ に送信されますthankyou.php。コードは問題なく送信されますが、メールが送信されません。どうすれば修正できますか?

ベストアンサー1

この回答には関数自体の使用法にのみ適用される部分もありますがmail()、これらのトラブルシューティング手順の多くは、どの PHP メール システムにも適用できます。

スクリプトがメールを送信しない理由はさまざまです。明らかな構文エラーがない限り、これらの原因を診断するのは困難です。明らかな構文エラーがない場合は、以下のチェックリストを実行して、潜在的な落とし穴を見つける必要があります。

エラー報告が有効になっており、すべてのエラーを報告するように設定されていることを確認します

エラー レポートは、コード内のバグや PHP で発生する一般的なエラーを根絶するために不可欠です。これらのエラーを受信するには、エラー レポートを有効にする必要があります。次のコードを PHP ファイルの先頭 (またはマスター構成ファイル) に配置すると、エラー レポートが有効になります。

error_reporting(-1);
ini_set('display_errors', 'On');
set_error_handler("var_dump");

見るPHP で役立つエラー メッセージを取得するにはどうすればよいでしょうか?この答え詳細についてはこちらをご覧ください。

mail()関数が呼び出されていることを確認する

馬鹿げているように思えるかもしれませんが、よくあるエラーは、関数をコード内に実際に配置することを忘れることですmail()。関数が存在し、コメント アウトされていないことを確認してください。

mail()関数が正しく呼び出されていることを確認する

bool mail ( 文字列 $to, 文字列 $subject, 文字列 $message [, 文字列 $additional_headers [, 文字列 $additional_parameters ]] )

mail 関数は 3 つの必須パラメータと、オプションで 4 番目と 5 番目のパラメータを取ります。呼び出しにmail()少なくとも 3 つのパラメータがない場合、呼び出しは失敗します。

呼び出しにmail()正しいパラメータが正しい順序で指定されていない場合も、呼び出しは失敗します。

サーバーのメールログを確認する

ウェブ サーバーは、そのサーバーを経由した電子メールの送信試行をすべてログに記録する必要があります。これらのログの場所はさまざまですが (サーバー管理者に場所を問い合わせる必要がある場合があります)、通常は の下にあるユーザーのルート ディレクトリにありますlogs。ログには、電子メールの送信試行に関連してサーバーが報告したエラー メッセージ (ある場合) が含まれます。

ポート接続障害の確認

ポート ブロックは、SMTP を使用して電子メールを配信するコードを統合する際に、ほとんどの開発者が直面する非常に一般的な問題です。また、これはサーバーのメール ログで簡単に追跡できます (メール ログのサーバーの場所は、上で説明したように、サーバーごとに異なる場合があります)。共有ホスティング サーバーを使用している場合、ポート 25 と 587 はデフォルトでブロックされたままです。このブロックは、ホスティング プロバイダーによって意図的に行われています。これは、一部の専用サーバーにも当てはまります。これらのポートがブロックされている場合は、ポート 2525 を使用して接続してみてください。ポートもブロックされている場合は、ホスティング プロバイダーに連絡してこれらのポートのブロックを解除するしか解決策はありません。

ほとんどのホスティング プロバイダーは、ネットワークからのスパム メールの送信を防ぐために、これらのメール ポートをブロックします。

プレーン/TLS 接続にはポート 25 または 587 を使用し、SSL 接続にはポート 465 を使用します。ほとんどのユーザーの場合、一部のホスティング プロバイダーによって設定されたレート制限を回避するためにポート 587 を使用することをお勧めします。

エラー抑制演算子を使用しない

ときエラー抑制演算子 @PHP の式の先頭にこの演算子を追加すると、その式によって生成されるエラー メッセージはすべて無視されます。この演算子の使用が必要な状況もありますが、メールの送信はそのうちの 1 つではありませ

コードに が含まれている場合@mail(...)、デバッグに役立つ重要なエラー メッセージが隠れている可能性があります。 を削除して@、エラーが報告されるかどうかを確認してください。

これは、確認するerror_get_last()具体的な失敗については、その直後に。

mail()戻り値を確認する

mail()関数:

TRUEメールが正常に配達を受け付けた場合は を返し、そうでない場合は を返しますFALSE。メールが配達を受け付けたからといって、メールが実際に目的の宛先に届くわけではないことに注意してください。

これは次の理由で重要です:

  • 戻り値を受け取った場合、FALSEエラーはメールを受信するサーバーにあることがわかります。これはおそらくコーディングの問題ではなく、サーバー構成の問題です。なぜこのようなことが起こるのかを知るには、システム管理者に相談する必要があります。
  • 戻り値を受け取った場合、TRUEメールが確実に送信されるというわけではありません。メールが PHP によってサーバー上のそれぞれのハンドラーに正常に送信されたことを意味します。メールが送信されない原因となる、PHP の制御外の障害ポイントはまだあります。

これはFALSE正しい方向を示すのに役立ちますが、必ずしもメールが正常に送信されたことを意味するTRUEわけではありません。この点は重要です。

ホスティングプロバイダーがメールの送信を許可し、メールの送信を制限していないことを確認してください。

多くの共有ウェブホスト、特に無料ウェブホスティング プロバイダーは、自社のサーバーからのメール送信を許可しないか、一定期間に送信できるメールの量を制限しています。これは、スパマーが自社の安価なサービスに悪用するのを阻止するための取り組みによるものです。

ホストにメール送信の制限がある、またはメールの送信がブロックされていると思われる場合は、FAQ をチェックして、そのような制限が記載されていないか確認してください。そうでない場合は、サポートに連絡して、メールの送信に関して制限が課されているかどうかを確認する必要があるかもしれません。

スパムフォルダをチェックして、メールがスパムとしてフラグ付けされないようにする

多くの場合、さまざまな理由により、PHP (およびその他のサーバー側プログラミング言語) を介して送信された電子メールは受信者のスパム フォルダーに送られてしまいます。コードのトラブルシューティングを行う前に、必ずそこを確認してください。

PHP経由で送信されたメールが受信者のスパムフォルダに送られないようにするには、PHPコード内とそれ以外の部分の両方で、メールがスパムとしてマークされる可能性を最小限に抑えるためのさまざまな方法があります。ミヒール・デ・マーレ含む:

  • 次のような電子メール認証方法を使用するSPF、 そしてDKIMメールとドメイン名が関連していることを証明し、ドメイン名のなりすましを防止します。SPF Web サイトには、サイトの DNS 情報を生成するウィザードが含まれています。
  • チェックあなたの逆DNSメール サーバーの IP アドレスが、メールの送信に使用するドメイン名を指していることを確認します。
  • 使用しているIPアドレスがブラックリストに載っていない
  • 返信先アドレスが有効で、存在するアドレスであることを確認してください。
  • [宛先] フィールドには、電子メール アドレスだけでなく、受信者の完全な実名 (例) を入力します。"John Smith" <[email protected]>
  • [email protected]やなどの不正アカウントを監視します[email protected]。つまり、これらのアカウントが存在することを確認し、アカウントに送信された内容を読み、苦情に対応するということです。
  • 最後に、登録解除が非常に簡単になるようにしてください。そうしないと、ユーザーはスパムボタンを押して登録解除してしまい、評判に影響を及ぼします。

見るプログラムで送信した電子メールが自動的にスパムとしてマークされないようにするにはどうすればよいですか?このトピックの詳細については、こちらをご覧ください。

すべてのメールヘッダーが提供されていることを確認してください

一部のスパム ソフトウェアでは、「From」や「Reply-to」などの一般的なヘッダーが欠落しているメールを拒否します。

$headers = array("From: [email protected]",
    "Reply-To: [email protected]",
    "X-Mailer: PHP/" . PHP_VERSION
);
$headers = implode("\r\n", $headers);
mail($to, $subject, $message, $headers);

メールヘッダーに構文エラーがないことを確認する

無効なヘッダーは、ヘッダーがないのと同じくらい悪いです。 1 つの間違った文字がメールを台無しにする可能性があります。 PHP はこれらのエラーを検出しないため、構文が正しいことを再確認してください

$headers = array("From [email protected]", // missing colon
    "Reply To: [email protected]",      // missing hyphen
    "X-Mailer: "PHP"/" . PHP_VERSION      // bad quotes
);

From:偽の送信者を使用しないでください

メールには From: 送信者がいる必要がありますが、任意の値を使用することはできません。特に、ユーザーが指定した送信者アドレスは、メールをブロックする確実な方法です。

$headers = array("From: $_POST[contactform_sender_email]"); // No!

理由: ウェブ サーバーまたは送信メール サーバーが SPF/DKIM ホワイトリストに登録されていないため、@hotmail または @gmail アドレスの責任を負っているように見せかけられません。From:設定されていない送信者ドメインのメールを黙ってドロップする可能性もあります。

受信者の値が正しいことを確認してください

問題は、電子メールの受信者の値が間違っているという単純なものである場合があります。これは、間違った変数を使用していることが原因である可能性があります。

$to = '[email protected]';
// other variables ....
mail($recipient, $subject, $message, $headers); // $recipient should be $to

これをテストする別の方法は、受信者の値をmail()関数呼び出しにハードコードすることです。

mail('[email protected]', $subject, $message, $headers);

これはすべてのmail()パラメータに適用できます。

複数のアカウントに送信する

メール アカウントの問題を排除するには、異なるメール プロバイダーの複数のメール アカウントにメールを送信します。メールがユーザーの Gmail アカウントに届かない場合は、同じメールを Yahoo アカウント、Hotmail アカウント、通常の POP3 アカウント (ISP 提供のメール アカウントなど) に送信します。

メールが他のメール アカウントのすべてまたは一部に届く場合、コードがメールを送信していることはわかりますが、メール アカウント プロバイダーが何らかの理由でメールをブロックしている可能性があります。メールがどのメール アカウントにも届かない場合、問題はコードに関連している可能性が高くなります。

コードがフォームメソッドと一致していることを確認してください

フォーム メソッドを に設定した場合はPOST、フォーム値の検索に を使用していることを確認してください$_POST。 に設定した場合、GETまたはまったく設定しなかった場合は、フォーム値の検索に を使用していることを確認してください$_GET

フォームのaction値が正しい場所を指していることを確認してください

フォームaction属性に PHP メール送信コードを指す値が含まれていることを確認してください。

<form action="send_email.php" method="POST">

Webホストが電子メールの送信をサポートしていることを確認する

一部の Web ホスティング プロバイダーでは、自社のサーバー経由での電子メールの送信を許可または有効化していません。理由はさまざまですが、プロバイダーが電子メールの送信を無効化している場合は、サードパーティを利用して電子メールを送信する代替方法を使用する必要があります。

テクニカル サポートにメールを送信すると (オンライン サポートまたは FAQ を参照した後)、サーバー上で電子メール機能が利用可能かどうかが明確になります。

localhostメールサーバーが設定されていることを確認する

WAMP、MAMP、または XAMPP を使用してローカル ワークステーションで開発している場合、ワークステーションに電子メール サーバーがインストールされていない可能性があります。電子メール サーバーがインストールされていないと、PHP はデフォルトでメールを送信できません。

基本的なメールサーバーをインストールすることで、この問題を解決できます。Windowsの場合は、無料のマーキュリーメール

SMTPを使用してメールを送信することもできます。この素晴らしい答えからヴィカス・ドゥイヴェディこれを実行する方法を学ぶ。

PHPのカスタムを有効にするmail.log

MTAとPHPのログファイルに加えて、mail()関数のログ記録具体的には、SMTP のやり取り全体は記録されませんが、少なくとも関数呼び出しパラメータと呼び出しスクリプトは記録されます。

ini_set("mail.log", "/tmp/mail.log");
ini_set("mail.add_x_header", TRUE);

見るhttp://php.net/manual/en/mail.configuration.php詳細については、 を参照してください。(これらのオプションは、またはphp.iniで有効にすることをお勧めします。).user.ini.htaccess

メールテストサービスで確認する

MTA/Web サーバーの設定をテストするために利用できる、配信およびスパムチェックのさまざまなサービスがあります。通常は、メール プローブを To: アドレスに送信し、配信レポートと、後でより具体的な障害または分析を取得します。

別のメーラーを使用する

PHPの組み込みmail()関数は便利で、多くの場合は目的を達成しますが、欠点もある幸いなことに、上記で概説した多くの問題に対処できる、より強力で柔軟性の高い代替手段があります。

これらすべてを、プロフェッショナルな SMTP サーバー/サービス プロバイダーと組み合わせることができます。(典型的な 08/15 共有 Web ホスティング プランは、電子メールのセットアップ/構成に関しては当たり外れがあるためです。)

おすすめ記事