【发布时间】:2012-02-01 21:49:10
【问题描述】:
(因为这是我的第一个 SO 问题,所以我只想说我希望它不是 Zend 特定的。据我所知,这应该不是问题。虽然我可以将它发布在Zend-specific forum,我觉得我至少有可能在这里得到一个好的答案,特别是因为答案可能涉及超越 Zend Framework 的 MIME 相关问题。我基本上是想了解我的问题是否面对应该被认为是 ZF 错误,或者如果我误解或滥用它。)
我一直在使用 Zend_Mail 构建通过 SendGrid(一种电子邮件分发服务)发送的 MIME 消息。他们的平台允许您通过他们的 SMTP 服务器发送电子邮件,但是当您使用特殊标头 (X-SMTPAPI) 时提供附加功能,该标头的值是 JSON 编码的专有参数字符串,可能会很长。
最终,我传递的标头太长(我认为 >1000 个字符),并且出现错误。我很困惑,因为在我将值传递给 Zend_Mail::addHeader() 之前,我知道它是通过 PHP 的本机 wordwrap() 函数传递的,所以我认为行长应该永远不会成为问题。
事实证明,addHeader() 非常刻意地去除换行符,并没有通过 cmets 进行具体解释。
// In Zend_Mail::addHeader()
$value = $this->_filterOther($value);
// In Zend_Mail::_filterOther()
$rule = array("\r" => '',
"\n" => '',
"\t" => '',
);
return strtr($data, $rule);
好的,起初这似乎是合理的——也许 ZF 想要完全控制格式和换行。 Zend_Mail::addHeader() 中调用的下一个方法是
$value = $this->_encodeHeader($value);
这个方法对值进行编码(无论是quoted-printable 还是base64,视情况而定)并将其分块成适当长度的行,但仅如果它包含“不可打印的字符”,由 Zend_Mime 确定::isPrintable($value)。
查看该方法,换行符 (\n) 确实被视为不可打印字符!因此,如果在之前的方法调用中没有将它们从字符串中删除,那么长标头将被编码为 QP 并分块为 72 个字符的行,一切都会正常工作。事实上,我做了一个测试,我注释掉了对 _filterOther() 的调用,并且长标头被编码并且没有问题地通过。但是现在我只是对 ZF 进行了粗心的 hack,并没有真正理解我删除的线路背后的目的,所以这不是一个长期的解决方案。
我的中期解决方案是扩展 Zend_Mail 并创建一个新方法 addHeaderForceEncode(),它将始终对标头的值进行编码,因此始终将其分块为短行。但我仍然不满意,因为我不明白为什么首先需要调用 _filterOther() —— 也许我根本不应该解决它。
谁能向我解释为什么存在这种剥离换行符的行为?如果标题不包含换行符以外的任何“不可打印字符”,这似乎不可避免地会导致标题过长的情况。
我在这个主题上做了很多不同的搜索,并查看了一些 ZF 错误报告,但没有看到任何人谈论这个。令人惊讶的是,这似乎是一个非常模糊的问题。仅供参考,我正在使用 ZF 1.11.11。
更新:如果有人想关注我打开的 ZF 问题,这里是:Zend_Mail::addHeader() UNfolds long headers, then throws exception
【问题讨论】:
-
StackOverflow 可以回答所有问题 ;) +1 对于您的第一个问题。
-
感谢您让我感到宾至如归。
标签: php zend-framework smtp mime zend-mail