可靠地发送电子邮件并可靠地处理错误

时间:2013-04-22 05:45:41

标签: php email pear

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

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

1 个答案:

答案 0 :(得分:3)

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

  1. 应用程序:将邮件放入本地传递代理的队列
  2. 传递代理:将邮件发送到配置的SMTP服务器
  3. SMTP服务器:将邮件发送到目标邮件服务器
  4. 用户邮件应用程序:从邮件服务器获取邮件
  5. 用户:点击邮件,阅读
  6. PHP的mail()函数将邮件放入unix上本地邮件传递代理的队列中。如果不起作用,您将只会收到错误(返回值false)。当代理无法进一步发送邮件或执行任何步骤2-5时,您不会收到通知。

    使用与SMTP服务器的直接SMTP连接至少可以为您提供邮件无法传递到SMTP服务器的情况,这比mail()提供的信息更多。如果邮件没有被读取或者被简单地过滤到垃圾邮件文件夹,或者远程邮件帐户不存在(3-5),那么您没有得到的信息。

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

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

    可靠性&amp;鲁棒性

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

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