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

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

问题描述

我有点担心,如果这个功能发送的电子邮件可以被正确识别在大多数的电子邮件和网络邮件客户端应该的方式,特别是我最关心的这个疑问:




  • UTF-8声明和附件是否形成良好?

  • 需要使用quoted_printable_decode()吗?如果是,哪里?

  • 内容传输编码:7或8位?我一直看到7,但是由于我发送了一个UTF-8编码的邮件,我不知道。

  • 我应该使用mb_send_mail()还是mail()是否足够? li>


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



编辑2:我知道其他替代品(图书馆)的电子邮件处理,但为了我自己的好奇心和知识,我只是想知道这个代码是100%好,或者如果它是buggy 。

  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 。''',
'Date:'。date('r',time()),
'From:'。$ name。'<'$ from。'> ',
'回复:'。$ name。'<'。$ from。'>',
'返回路径:'$ $。 '$ $'',
'X-Mailer:PHP'phpversion(),
'X优先级:2',
'X-MSMail优先级:高',
'X-Originating-IP:'。$ _SERVER ['SERVER_ADDR'],
);

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

foreach($ to as $ key => $ value)
{
$至[$ 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(\\\
,$附件)。 \\\
;
}

$ message = array

'这是MIME格式的多部分消息',
'',
'--Mixed'。$ boundary,
'Content-Type:multipart / alternative; boundary =Alt'。$ boundary。'',
'',
' Alt $。$ border,
'Content-Type:text / plain; charset =UTF-8',
'Content-Disposition:inline',
'Content-Transfer-Encoding :8bit',
'',
trim(strip_tags($ message,'< a>')),
'',
'--Alt' ,
'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;
}


解决方案

将强烈建议您使用预建的邮件/ SMTP类,例如 Zend_Mail 。虽然我不认为整个Zend框架是猫的睡衣,但我对邮件处理代码有很好的看法。



编辑:我还应该补充一点使用预建的邮件/ SMTP类将会抽出几部分电子邮件的复杂性/结构。



更新2009-05-06:



  • UTF-8声明和附件是否形成良好?


他们看起来不错。



  • 我需要使用 quoted_printable_decode()?如果是,在哪里?


否。只有在解码电子邮件时,才想使用 quoted_printable_decode()。不是当你编码一个。你应该使用 quoted_printable_encode() ?我将在下面讨论一下。



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


如果您知道目标SMTP服务器可以支持,则仅使用8位编码。但是,由于您将电子邮件传递到本地MTA,因此建议不要设置此值。默认值为7位编码,但它具有自己的限制条件:每行代码范围为1-127的高达998个八位字节,CR和LF只允许作为CRLF行的一部分显示( http://tools.ietf.org/html/rfc2045#section-2.7 )。



我建议您使用Quoted-Printable( http://tools.ietf.org/html/rfc2045#section-6.7 )内容传输编码。你在哪里调用 trim(strip_tags($ message,'< a>')) trim($ message)你将要包含 quoted_printable_encode(trim(...))



  • 我应该使用 mb_send_mail()还是 mail() / li>

如果你知道你是要处理多字节消息日语,韩语,中文等)然后 mail()应该足够了。



现在我已经回答您的初始问题,让我告诉您一些问题存在。


  1. 您正在指定您的纯文本和Html内容部分的字符集是UTF-8,但是它并没有出现,因为您确实确实是UTF-8编码的。

  2. 您正在检查 null $ $ bcc $附件在进一步处理之前但是,当他们可能实际上是 null 时,你没有做任何事情。因此,如果您碰巧收到 $ null ,则不会处理该变量,但是您继续发送电子邮件到 null

截至目前,这就是我要进去,但我仍然会强烈建议一个预先建立的解决方案,因为他们有很多用户/时间来解决错误。


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:

  • Are the UTF-8 declarations and attachments well formed?
  • Do I need to use quoted_printable_decode()? If yes, where?
  • Content-Transfer-Encoding: 7 or 8 bits? I've always seen 7 but since I'm sending a UTF-8 encoded mail I'm not sure.
  • Should I use mb_send_mail() or mail() is enough?

EDIT: I don't know why but the code is not showing up correctly, I made it available @ http://gist.github.com/104818

EDIT 2: I'm aware of other alternatives (libraries) for email handling, but for the sake of my own curiosity and knowledge I just wish to know if this code is 100% good, or if it's buggy.

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("\n", $attachments[$key]);
            }

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

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

    $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("\n", $message), implode("\n", $headers)) === true)
    {
        return true;
    }

    return false;
}

解决方案

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.

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

Update 2009-05-06: Answering your question directly.

  • Are the UTF-8 declarations and attachments well formed?

They look decent enough.

  • Do I need to use quoted_printable_decode()? If yes, where?

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.

  • Content-Transfer-Encoding: 7 or 8 bits? I've always seen 7 but since I'm sending a UTF-8 encoded mail I'm not sure.

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 (http://tools.ietf.org/html/rfc2045#section-2.7).

I would recommend you use the Quoted-Printable (http://tools.ietf.org/html/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(...)).

  • Should I use mb_send_mail() or mail() is enough?

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. 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天全站免登陆