无法使用 phpmailer 从 php 签署 DKIM 电子邮件
Posted
技术标签:
【中文标题】无法使用 phpmailer 从 php 签署 DKIM 电子邮件【英文标题】:can't sign DKIM email from php with phpmailer 【发布时间】:2015-10-13 22:49:40 【问题描述】:我在使用 PHPMailer (v 5.2.9) 发送 DKIM 签名电子邮件时遇到问题。
我使用的 SMTP 服务器 (realsender.com) 应该对我发送的每封电子邮件进行签名。 当我从 Delphi 程序发送电子邮件时它可以工作,但它不适用于 PHP。
我已经检查了 phpMailer 和 Delphi 发送的电子邮件,https://www.mail-tester.com
Delphi 的结果是 10/10,PHP 的结果是 6.8/10。 这是使用 PHPMailer 发送电子邮件的文件的一部分:
$mail = new PHPMailer();
$mail->CharSet = 'UTF-8';
$mail->setLanguage('it');
$mail->isSMTP();
$mail->Host = SMTP_HOST;
$mail->SMTPAuth = SMTP_AUTH;
$mail->Username = SMTP_USERNAME;
$mail->Password = SMTP_PASSWORD;
if (defined('SMTP_PORT'))
$mail->Port = SMTP_PORT;
if (defined('SMTP_SECURE'))
$mail->SMTPSecure = SMTP_SECURE;
if(defined('DKIM_DOMAIN'))
$mail->DKIM_domain=DKIM_DOMAIN;
$mail->DKIM_selector=DKIM_SELECTOR;
$mail->DKIM_private=DKIM_PRIVATE;
[...]//setting from, to, subject and body
$mail->send();
注意:$mail->send();
总是返回 true。
首先我尝试在不设置 DKIM_ 属性的情况下发送电子邮件,然后我尝试与他们一起发送。 在这两种情况下,结果都是无效的 DKIM 标志和 6.8 分。
我已向 SMTP 支持部门询问他们是否对此有所了解,但他们说这可能是 PHPMailer 本身的问题。
我可以做些什么来创建一个有效的 DKIM?
提前致谢。
更新: 我发现问题出在电子邮件的正文中。 我也停止使用 DKIM_ vars,因为我的 SMTP 服务器会自动签署所有电子邮件。 发送空邮件,不带标签或带标签但不带文字都可以(9.9),否则得分为6.8。 还有一点 html 电子邮件(带有链接和 div)也可以。 会是什么?
【问题讨论】:
您是否使用var_dump
验证了DKIM_*
常量?
看看DKIM unit test。您还可以通过启用异常获得更多错误报告:$mail = new PHPMailer(true);
。最新的 PHPMailer 是 5.2.10,但没有与 DKIM 相关的更改。
【参考方案1】:
我明白了! 我不得不将邮件正文分成小块(每个块最多 990 个字符),原因(在此解释:http://permalink.gmane.org/gmane.mail.postfix.user/223780)是:
损坏的一个可能原因是发送应用程序生成的电子邮件在某些方面与 RFC 5322 或 RFC 5321 不兼容。
超过 990 行。
Postfix SMTP 客户端将行长度保持在 1000 字节的 SMTP 协议限制以下,包括 .由于此更改是在签名后发生的,因此肯定会破坏 DKIM 签名。
为避免长行损坏问题,请以带引号的可打印或 base64 编码发送邮件,行长最多为 80 个字符。
这是我用来分割字符串的代码:
function create_html_email_from_string($str)
if(!is_string($str))
return false;
return '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><body>'
.html_long_lines_split($str).'</body></html>';
/**
* this function insert line endings (\r\n) after the ending of <br>, <p> and <div> tags because if you only use chunk_split_unicode it can break links and any other tags and css.
*/
function html_long_lines_split($str)
$str = str_ireplace(['<br>','<br/>','<br />'], "<br/>\r\n", $str);
$str = str_ireplace('</p>', "</p>\r\n", $str);
$str = str_ireplace('</div>', "</div>\r\n", $str);
//checks if there are lines longer than 990 bytes
$chunks=explode("\r\n", $str);
foreach ($chunks as $k=>$c)
if(strlen($chunks[$k])>990)
$chunks[$k]=chunk_split_unicode($chunks[$k], 500);
return implode("\r\n", $chunks);
/**
* @link http://php.net/manual/en/function.chunk-split.php#107711<br>
*/
function chunk_split_unicode($str, $l = 76, $e = "\r\n")
$tmp = array_chunk(
preg_split("//u", $str, -1, PREG_SPLIT_NO_EMPTY), $l);
$str = "";
foreach ($tmp as $t)
$str .= join("", $t) . $e;
return $str;
//$mail is an instance of PHPMailer
$mail->msgHTML(create_html_email_from_string($body));
【讨论】:
以上是关于无法使用 phpmailer 从 php 签署 DKIM 电子邮件的主要内容,如果未能解决你的问题,请参考以下文章
警告:require_once(Composer/PHPMailer/vendor/phpmailer/phpmailer/src/autoload.php):无法打开流:没有这样的文件或目录
使用 phpmailer 从 Gmail 发送电子邮件。登录错误