这是使用 PHP 发送电子邮件的正确方法吗? [英] Is this the correct way to send email with PHP?

查看:17
本文介绍了这是使用 PHP 发送电子邮件的正确方法吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有点担心此功能是否以应有的方式发送可以在大多数电子邮件和网络邮件客户端上正确识别的电子邮件,特别是我最担心的问题:

I'm a bit worried if this function sends emails that can be recognized correctly on the majority of email and webmail clients the way it should, specifically I'm most concerned about this doubts:

  • UTF-8 声明和附件的格式是否正确?
  • 我需要使用quoted_printable_decode()吗?如果是,在哪里?
  • 内容传输编码:7 位还是 8 位?我一直看到 7,但由于我发送的是 UTF-8 编码的邮件,所以我不确定.
  • 我应该使用 mb_send_mail() 还是 mail() 就足够了?

我不知道为什么但代码没有正确显示,我让它可用@ http://gist.github.com/104818

编辑 2:我知道电子邮件处理的其他替代方案(库),但为了我自己的好奇心和知识,我只想知道这段代码是否 100% 好,或者它是否有问题.

function Email($name, $from, $to, $subject, $message, $bcc = null, $attachments = null)
{
    ini_set('SMTP', 'localhost');
    ini_set('sendmail_from', $from);

    $name = filter_var($name, FILTER_SANITIZE_STRING);
    $from = filter_var($from, FILTER_SANITIZE_EMAIL);
    $subject = filter_var($subject, FILTER_SANITIZE_STRING);

    $boundary = '_Boundary_' . md5(microtime(true) . mt_rand(0, PHP_INT_MAX));

    $headers = array
    (
        'MIME-Version: 1.0',
        'Content-Type: multipart/mixed; boundary="Mixed' . $boundary . '"',
        'Date: ' . date('r', time()),
        'From: "' . $name . '" <' . $from . '>',
        'Reply-To: "' . $name . '" <' . $from . '>',
        'Return-Path: "' . $name . '" <' . $from . '>',
        'X-Mailer: PHP ' . phpversion(),
        'X-Priority: 2',
        'X-MSMail-Priority: High',
        'X-Originating-IP: ' . $_SERVER['SERVER_ADDR'],
    );

    if (is_null($to) === false)
    {
        if (is_array($to) === false)
        {
            $to = explode(',', $to);
        }

        foreach ($to as $key => $value)
        {
            $to[$key] = filter_var($value, FILTER_SANITIZE_EMAIL);
        }

        $to = implode(', ', array_filter($to));
    }

    if (is_null($bcc) === false)
    {
        if (is_array($bcc) === false)
        {
            $bcc = explode(',', $bcc);
        }

        foreach ($bcc as $key => $value)
        {
            $bcc[$key] = filter_var($value, FILTER_SANITIZE_EMAIL);
        }

        $headers[] = 'BCC: ' . implode(', ', array_filter($bcc));
    }

    if (is_null($attachments) === false)
    {
        settype($attachments, 'array');

        foreach ($attachments as $key => $value)
        {
            if (is_file($value) === true)
            {
                $attachments[$key] = array
                (
                    '',
                    '--Mixed' . $boundary,
                    'Content-Type: application/octet-stream; name="' . basename($value) . '"',
                    'Content-Disposition: attachment; filename="' . basename($value) . '"',
                    'Content-Transfer-Encoding: base64',
                    '',
                    trim(chunk_split(base64_encode(file_get_contents($value)))),
                );

                $attachments[$key] = implode("
", $attachments[$key]);
            }

            else
            {
                unset($attachments[$key]);
            }
        }

        $attachments = implode("
", $attachments) . "
";
    }

    $message = array
    (
        'This is a multi-part message in MIME format.',
        '',
        '--Mixed' . $boundary,
        'Content-Type: multipart/alternative; boundary="Alt' . $boundary . '"',
        '',
        '--Alt' . $boundary,
        'Content-Type: text/plain; charset="UTF-8"',
        'Content-Disposition: inline',
        'Content-Transfer-Encoding: 8bit',
        '',
        trim(strip_tags($message, '<a>')),
        '',
        '--Alt' . $boundary,
        'Content-Type: text/html; charset="UTF-8"',
        'Content-Disposition: inline',
        'Content-Transfer-Encoding: 8bit',
        '',
        trim($message),
        '',
        '--Alt' . $boundary . '--',
        $attachments,
        '--Mixed' . $boundary . '--',
    );

    if (@mail($to, stripslashes($subject), implode("
", $message), implode("
", $headers)) === true)
    {
        return true;
    }

    return false;
}

推荐答案

虽然这应该可行,但我强烈建议使用预构建的 Mail/SMTP 类,例如 Zend_Mail.虽然我不认为整个 Zend 框架是猫的睡衣,但我对他们的邮件处理代码有很好的看法.

While that should work, I would strongly recommend using a prebuilt Mail/SMTP class such as Zend_Mail. While I don't think the whole Zend Framework is the cat's pajamas, I do have a very good opinion of their mail handling code.

我还应该补充一点,使用预构建的 Mail/SMTP 类将抽象多部分电子邮件的几乎所有复杂性/结构.

I should also add that using a prebuilt Mail/SMTP class will abstract almost all of the complexity/structure of multi-part emails.

2009-05-06 更新:直接回答您的问题.

  • UTF-8 声明和附件的格式是否正确?

他们看起来还不错.

  • 我需要使用 quoted_printable_decode() 吗?如果是,在哪里?
  • Do I need to use quoted_printable_decode()? If yes, where?

没有.只有在解码电子邮件消息时,才需要使用 quoted_printable_decode().不是当你编码一个.你应该使用 quoted_printable_encode() 吗?我接下来会讨论这个.

No. You would want to use quoted_printable_decode() only if you are decoding an email message. Not when you are encoding one. Should you use quoted_printable_encode()? I will discuss this next.

  • 内容传输编码:7 位还是 8 位?我一直看到 7,但由于我发送的是 UTF-8 编码的邮件,所以我不确定.

如果您知道目标 SMTP 服务器可以支持它,则仅使用 8 位编码.但是,由于您将电子邮件传递给本地 MTA,我不建议设置此值.默认值是 7 位编码,但它有自己的一组限制:代码范围 1-127 的每行最多 998 个八位字节,其中 CR 和 LF 只允许作为 CRLF 行结尾的一部分出现 (https://www.rfc-editor.org/rfc/rfc2045#section-2.7).

Only use 8bit encoding if you know that the destination SMTP server can support it. However, since you are passing your email off to the local MTA, I wouldn't recommend setting this value. The default value is 7bit encoding, but it has it's own set of restrictions: up to 998 octets per line of the code range 1-127 with CR and LF only allowed to appear as part of the CRLF line ending (https://www.rfc-editor.org/rfc/rfc2045#section-2.7).

我建议您使用 Quoted-Printable (https://www.rfc-editor.org/rfc/rfc2045#section-6.7) 内容传输编码.在您调用 trim(strip_tags($message, '<a>'))trim($message) 的地方,您需要用 quoted_printable_encode 括起来(trim(...)).

I would recommend you use the Quoted-Printable (https://www.rfc-editor.org/rfc/rfc2045#section-6.7) Content-Transfer-Encoding. Where you are calling trim(strip_tags($message, '<a>')) and trim($message) you will want to enclose those with quoted_printable_encode(trim(...)).

  • 我应该使用 mb_send_mail() 还是 mail() 就足够了?
  • Should I use mb_send_mail() or mail() is enough?

如果您知道自己不会处理多字节消息(日语、韩语、中文等),那么 mail() 就足够了.

If you know you are not going to be handling Multibyte messages (Japanese, Korean, Chinese, etc.) then mail() should suffice.

既然我已经回答了你最初的问题,让我告诉你哪里存在一些问题.

Now that I've answered your initial questions, let me tell you where some problems exist.

  1. 您指定纯文本和 Html 内容部分的字符集是 UTF-8,但它并未出现,因为您实际上是在确保它们确实是 UTF-8 编码的.
  2. 在进一步处理它们之前,您正在检查 $to$bcc$attachments 中的 null,但是,当它们实际上可能为 null 时,您并没有做任何事情.因此,如果您碰巧收到 $tonull,则不会处理该变量,而是继续向 null 发送电子邮件>.
  1. You are specifying that the Character set of your Plain Text and Html content parts are UTF-8, however it doesn't appear as you are actually ensuring that they really are UTF-8 encoded.
  2. You are checking for null in $to, $bcc, $attachments before you further process them, however, you aren't doing anything when they may actually be null. So, if you happen to receive a null for $to, you don't process the variable, but you continue to send an email to null.

到目前为止,这就是我要讨论的全部内容,但我仍然强烈推荐一个预先构建的解决方案,因为他们有很多用户/时间来解决错误.

As of right now, that's all I am going to go into but I am still going to highly recommend a pre-built solution as they have had lots of users/time to work out bugs.

这篇关于这是使用 PHP 发送电子邮件的正确方法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆