我有点担心,如果这个功能发送的电子邮件可以在大多数电子邮件和网络邮件客户端上正确识别,特别是我最担心的是这个问题:
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("\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, '')), '', '--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; }
Jordan S. Jo.. 27
虽然这应该工作,但我强烈建议使用预构建的邮件/ SMTP类,如Zend_Mail.虽然我不认为整个Zend Framework是猫的睡衣,但我确实对他们的邮件处理代码有很好的看法.
编辑:我还应该补充说,使用预建的邮件/ 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)Content-Transfer-Encoding.你在哪里打电话trim(strip_tags($message, ''))
,trim($message)
你会想要把那些包围起来quoted_printable_encode(trim(...))
.
我应该使用
mb_send_mail()
还是mail()
足够?
如果您知道您不会处理多字节消息(日语,韩语,中文等),那么mail()
就足够了.
既然我已回答了您的初步问题,请告诉您存在哪些问题.
您指定纯文本和Html内容部分的字符集是UTF-8,但它并不显示,因为您实际上确保它们确实是UTF-8编码.
您在检查null
中$to
,$bcc
,$attachments
然后再对其进行处理,但是,你没有做任何事情时,他们实际上可能null
.因此,如果您碰巧收到了null
for $to
,则不会处理该变量,但您会继续向其发送电子邮件null
.
截至目前,这就是我要进行的所有内容,但我仍然强烈推荐预先构建的解决方案,因为他们有很多用户/时间来解决错误.
虽然这应该工作,但我强烈建议使用预构建的邮件/ SMTP类,如Zend_Mail.虽然我不认为整个Zend Framework是猫的睡衣,但我确实对他们的邮件处理代码有很好的看法.
编辑:我还应该补充说,使用预建的邮件/ 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)Content-Transfer-Encoding.你在哪里打电话trim(strip_tags($message, ''))
,trim($message)
你会想要把那些包围起来quoted_printable_encode(trim(...))
.
我应该使用
mb_send_mail()
还是mail()
足够?
如果您知道您不会处理多字节消息(日语,韩语,中文等),那么mail()
就足够了.
既然我已回答了您的初步问题,请告诉您存在哪些问题.
您指定纯文本和Html内容部分的字符集是UTF-8,但它并不显示,因为您实际上确保它们确实是UTF-8编码.
您在检查null
中$to
,$bcc
,$attachments
然后再对其进行处理,但是,你没有做任何事情时,他们实际上可能null
.因此,如果您碰巧收到了null
for $to
,则不会处理该变量,但您会继续向其发送电子邮件null
.
截至目前,这就是我要进行的所有内容,但我仍然强烈推荐预先构建的解决方案,因为他们有很多用户/时间来解决错误.
在大多数情况下,我都是为了自己动手,但是当涉及到邮件时,我会衷心地建议让自己更轻松,并使用像Swift Mailer或PHPMailer这样的东西(按此顺序,我的钱).
作为副奖金(假设您指定回复等),您被标记为垃圾邮件的可能性也大大降低.