1

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

  • php 的mail()功能 - 这在我测试它的第一天就起作用了,后来就停止了。我第一次意识到发送邮件不是“给定”的简单任务
  • 梨邮件类 - 今晚实施,目前仍在工作
  • pear smtp 邮件 -在此处阅读此内容。让我觉得我应该使用 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>");
    }
?>
4

1 回答 1

3

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

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

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

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

要知道远程帐户是否存在,您需要解析错误响应邮件(“未投递的邮件返回给发件人),或者实现完整的远程服务器 SMTP 连接并自行发送(第 3 步),我不建议这样做。

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

可靠性和稳健性

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

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

于 2013-04-22T08:40:57.050 回答