(由于这是我的第一个SO问题,所以我希望它不是太专门化于Zend。据我所知,这不应该是个问题。虽然我可以在特定于Zend的论坛上发布它,但我觉得我至少有同样可能在这里得到一个好答案,特别是因为答案可能涉及超越Zend框架的MIME相关问题。我基本上想要理解的是,我面临的问题是否应该被视为ZF的一个bug,或者我是否误解了某些东西或者误用了它。)
我一直在使用Zend_Mail来构建一个MIME消息,将其通过SendGrid(一种电子邮件分发服务)发送。他们的平台允许您通过他们的SMTP服务器发送电子邮件,但如果您使用一个特殊的标题(X-SMTPAPI),则会提供附加功能,其值是专有参数的JSON编码字符串,这可能会非常长。
最终,我传递的标题变得太长了(我认为>1000个字符),并且我遇到了错误。我感到困惑,因为我知道它在传递给Zend_Mail :: addHeader()之前,已经通过PHP的本地wordwrap()函数进行了换行处理,所以我认为行长度永远不应该成为问题。
事实证明,addHeader()非常有意地剥离换行符,没有通过注释进行任何特别的解释。
// In Zend_Mail::addHeader()
$value = $this->_filterOther($value);
// In Zend_Mail::_filterOther()
$rule = array("\r" => '',
"\n" => '',
"\t" => '',
);
return strtr($data, $rule);
一开始看起来这个想法很合理——也许Zend框架想要完全控制格式和换行。在Zend_Mail::addHeader()方法中调用的下一个方法是:
$value = $this->_encodeHeader($value);
该方法将值进行编码(适当时使用quoted-printable或base64),并将其分成适当长度的行,但仅在它包含"不可打印字符"时才这样做,由Zend_Mime::isPrintable($value)决定。
查看该方法,换行符(\n)确实被视为不可打印字符!因此,如果它们没有在前一个方法调用中被剥离出字符串,那么长标题将被编码为QP,并分成72个字符的行,一切都会正常工作。事实上,我进行了一项测试,注释掉_filterOther()的调用,并且长头部得到编码并顺利通过。但现在,我只是无意识地对ZF进行了破坏,而没有真正理解我删除的那行代码的目的,因此这不能成为长期解决方案。
我的中期解决方案是扩展Zend_Mail并创建一个新方法addHeaderForceEncode(),它将始终对标头的值进行编码,从而始终将其分成短行。但我仍然不满意,因为我不明白为什么首先要进行_filterOther()调用-也许我根本不应该绕过它。
有人能向我解释为什么会存在去除换行符的行为吗?似乎这不可避免地会导致头部在不包含任何"非打印字符"(除了换行符)时变得过长。
我已经进行了多次关于此主题的搜索,并查看了一些ZF错误报告,但没有看到任何人讨论这个问题。令人惊讶的是,它似乎是一个非常晦涩的问题。FYI,我正在使用ZF 1.11.11。
更新:如果有人想关注我关于此事发起的ZF问题,请点击此处:Zend_Mail::addHeader() UNfolds long headers, then throws exception。