Lin*_*usR 8 php mime zend-framework smtp zend-mail
(因为这是我的第一个问题,我只想说,我希望它不是特定于Zend的.据我所知,这应该不是问题.虽然我本可以在特定于Zend的论坛上发布它,但我我觉得我至少有可能在这里得到一个好的答案,特别是因为答案可能涉及超越Zend Framework的MIME相关问题.我基本上试图了解我面临的问题是否应被视为ZF错误,或者如果我误解了某些东西或误用了它.)
我一直在使用Zend_Mail来构建一个通过电子邮件分发服务SendGrid发送的MIME消息.他们的平台允许您通过他们的SMTP服务器发送电子邮件,但是当您使用特殊标头(X-SMTPAPI)时,它会提供附加功能,该标头的值是JSON编码的专有参数字符串,这可能会很长.
最终,我传递的标题太长了(我想> 1000个字符),我得到了错误.我很困惑,因为我知道它是通过PHP的本机wordwrap()函数传递之前我将值传递给Zend_Mail :: addHeader(),所以我认为行长度永远不会是一个问题.
事实证明,addHeader()非常刻意地删除换行符,并且没有通过注释进行特别说明.
// In Zend_Mail::addHeader()
$value = $this->_filterOther($value);
// In Zend_Mail::_filterOther()
$rule = array("\r" => '',
"\n" => '',
"\t" => '',
);
return strtr($data, $rule);
Run Code Online (Sandbox Code Playgroud)
好吧,这一开始似乎很合理 - 也许ZF希望完全控制格式和换行.Zend_Mail :: addHeader()中调用的下一个方法是
$value = $this->_encodeHeader($value);
Run Code Online (Sandbox Code Playgroud)
此方法对值进行编码(根据需要使用quoted-printable或base64)并将其块化为适当长度的行,但仅当它包含"不可打印的字符"时,由Zend_Mime :: isPrintable($ value)确定.
考虑到该方法,换行符(\n)确实被认为是不可打印的字符!因此,如果只是在前一个方法调用中没有将它们从字符串中剥离出来,那么长标题将被编码为QP并被分成72个字符行,并且一切都会正常工作.事实上,我做了一个测试,在那里我注释掉了对_filterOther()的调用,并且长标头被编码并且没有任何问题.但是现在我刚刚对ZF进行了粗心的破解而没有真正理解我删除的那条线背后的目的,所以这不是一个长期的解决方案.
我的中期解决方案是扩展Zend_Mail并创建一个新方法addHeaderForceEncode(),它始终对头的值进行编码,因此总是将其分成短线.但我仍然不满意,因为我不明白为什么首先需要_filterOther()调用 - 也许我根本不应该解决它.
任何人都可以向我解释为什么这种行为存在剥离换行符的问题?如果标题不包含除换行符之外的任何"不可打印的字符",它似乎不可避免地导致标题可能变得太长的情况.
我在这个主题上做了很多不同的搜索,并查看了一些ZF错误报告,但没有看到有人在谈论这个.令人惊讶的是,这似乎是一个非常模糊的问题.仅供参考我正在使用ZF 1.11.11.
更新:如果有人想跟随ZF问题,我打开了这个,这里是:Zend_Mail :: addHeader()解开长标题,然后抛出异常
你可能碰到了一些事情.根据RFC 2821,SMTP中的文本行不能超过1000个字符:
文字行
文本行的最大总长度包括1000个字符(不包括为透明度复制的前导点).使用SMTP服务扩展可能会增加此数量.
标头不能包含换行符,这可能是Zend剥离它们的原因.对于长标题,通常插入换行符(SMTP中的CRLF)和用于"换行"它们的选项卡.
RFC 822的摘录:
每个标题字段可以被视为ASCII字符的单个逻辑行,包括字段名称和字段主体.为方便起见,该概念实体的场体部分可以分成多线表示; 这被称为"折叠".一般规则是,只要存在线性白空间(不仅仅是LWSP-chars),就可以替换地插入紧接着一个LWSP-char的CRLF.
我会说该_encodeHeader()函数应该看一下行长度,如果标题长于某个魔术值,请执行"换行和制表符"以使其跨越多行.
| 归档时间: |
|
| 查看次数: |
877 次 |
| 最近记录: |