【问题标题】:Send email reliably and handle errors robustly可靠地发送电子邮件并可靠地处理错误
【发布时间】:2013-04-14 22:42:36
【问题描述】:

由于我一直是 Java 后端开发人员,因此我正在创建我的第一个学习练习网站。我正在设置一个用户注册表单,由于这将是我的用户第一次看到我的网站,我想确保我尽可能稳健地处理事情。通过一些试验,我遇到并实施了几乎所有这些解决方案:

  • php 的mail() 函数 - 这在我测试它的第一天就起作用了,后来就停止了。我第一次意识到发送邮件不是“给定”的简单任务
  • pear 邮件类 - 今晚实施,目前仍在工作
  • pear smtp 邮件 - 阅读此here。让我觉得我应该使用 smtp?

此时我已经意识到可靠地发送电子邮件并不像我最初想象的那么简单。我的问题是最可靠的邮件发送方式是什么,以及什么是处理异常的稳健方式?例如,如果 SMTP 是最可靠的方式,请解释原因并提供一个简单的错误处理示例。

对于发生的任何错误,它们是否会在执行某些自动重试时受益?我明白,仅仅因为我发送邮件并不意味着这个人会收到它,但我问的是最强大的解决方案是什么,因为我确信其他人已经这样做了 100 次。

为了证明我不只是一个懒惰的编码员,这是我目前为止一直在工作的 - 但我不知道这实际上有多强大(梨邮件):

<?php } else if ($_SERVER['REQUEST_METHOD'] == 'POST') {

    include('Mail.php');
    include('Mail/mime.php');

    $to = urldecode($_POST['email']);
    if (preg_match('(\r|\n)', $to)) {
        die('No email injection for you!');
    }

    $headers = array(
        'From'=>'tag <me@mysite.com>',
        'Subject'=>'Registration for mysite.com'
    );
    $text_body = 'boring text message';
    $html_body = '<html>
        <head><title>Welcome</title></head>
        <body>
            <p>slightly less boring message</p>
        </body>
    </html>';

    //Utilize the mime class to generate mime body and add mime headers
    $mime = new Mail_mime();
    $mime->setTXTBody($text_body);
    $mime->setHTMLBody($html_body);
    $body = $mime->get();
    $headers = $mime->headers($headers);

    //Utilize the mail class to send the mime mail
    $mail = Mail::factory('mail');
    $mail->send($to, $headers, $body);

    echo 'mail sent maybe?';
?>

编辑: 使用带有错误处理的 SMTP 的代码示例

<?php } else if ($_SERVER['REQUEST_METHOD'] == 'POST') {

    include('Mail.php');
    include('Mail/mime.php');

    $to = $_POST['email'];
    $to = urldecode($to);
    if (preg_match('(\r|\n)', $to)) {
        die('No email injection for you!');
    }

    $headers = array(
            'From'=>'tag <me@mysite.com>',
            'Subject'=>'Registration for mysite.com'
            );
    $text_body = 'boring text message';
    $html_body = '<html>
        <head><title>Welcome</title></head>
        <body>
            <p>slightly less boring message</p>
        </body>
    </html>';

    //Utilize the mime class to generate mime body and add mime headers
    $mime = new Mail_mime();
    $mime->setTXTBody($text_body);
    $mime->setHTMLBody($html_body);
    $body = $mime->get();
    $headers = $mime->headers($headers);

    //Utilize the mail class to send the mime mail
    $host = 'mail.mysite.com';
    $port = '26';
    $username = 'me@mysite.com';
    $password ='myPassword';

    $smtp = Mail::factory('smtp', array (
            'host' => $host,
            'port' => $port,
            'auth' => true,
            'username' => $username,
            'password' => $password
            ));
    $mail = $smtp->send($to, $headers, $body);

    if (PEAR::isError($mail)) {
        echo("<p>" . $mail->getMessage() . "</p>");
    } else {
        echo("<p>Message successfully sent!</p>");
    }
?>

【问题讨论】:

  • 不要重新发明轮子,那里有很多可靠的 php 邮件库。我最喜欢的是swiftmailer.org

标签: php email pear


【解决方案1】:

发送邮件通常涉及几个步骤:

  1. 应用:将邮件放入本地投递代理队列
  2. 投递代理:将邮件发送到配置的 SMTP 服务器
  3. SMTP 服务器:将邮件发送到目标邮件服务器
  4. 用户邮件应用程序:从邮件服务器获取邮件
  5. 用户:点击邮件,阅读

PHP 的mail() 函数将邮件放入unix 上本地邮件传递代理的队列中。如果这不起作用,您只会得到一个错误(返回值false)。当代理无法进一步递送邮件或步骤 2-5 中的任何一个时,您不会收到通知。

使用直接 SMTP 连接到您的 SMTP 服务器至少可以让您知道邮件是否无法传递到您的 SMTP 服务器,这比使用mail() 获得的信息更多。如果邮件没有被阅读或被简单地过滤到垃圾邮件文件夹中,或者远程邮件帐户不存在 (3-5),您不会得到信息。

要知道远程帐户存在,您需要解析错误响应邮件(“未投递的邮件返回给发件人),或者实现完整的远程服务器 SMTP 连接并发送自己(步骤 3),我会不推荐。

要确定邮件是否已被阅读,您可以嵌入“网络错误”,即显示在 HTML 邮件中并通知您邮件已显示的微小(可能清晰)图像。您可以使用它来将发送的邮件放入数据库,并在调用 Web Bug 图像 URL 时将它们标记为已读。 X 天内未阅读的邮件可以被视为“未阅读”或“失败”——但用户也可以简单地休假:)

可靠性和稳健性

当远程用户的邮件服务器关闭时,您自己的邮件服务器(第 3 步)会自动尝试重新发送邮件。如果这不起作用,您将收到诸如“邮件传递延迟 24 小时”之类的邮件,当它停止这样做时,您还会收到另一封邮件。

因此,一旦邮件在您的邮件服务器上,您就可以确定该服务器会尽其所能来传递它。

【讨论】:

  • 由于详细程度而标记为正确答案,这让我清楚地知道通过 SMTP 发送更可靠,因为我们正在消除更多潜在的断点。将添加一个答案,只是为通过 SMTP 发送的其他用户提供代码以及错误处理。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-28
  • 2010-11-23
  • 2023-03-29
  • 2013-03-06
  • 1970-01-01
  • 2016-02-29
  • 2011-07-13
相关资源
最近更新 更多