gpt4 book ai didi

php - 电子邮件主题分隔符中的重音词 - 我该如何阻止它?

转载 作者:可可西里 更新时间:2023-11-01 12:52:59 25 4
gpt4 key购买 nike

我们有一个自定义的 php 电子邮件营销应用程序,还有一个有趣的问题:如果邮件的主题行包含带重音的单词,它会“吞掉”它与下一个单词之间的空格。一个例子:短语

Ángel Ríos escucha y soprende

(至少通过 gmail 和 lotus notes)显示为

ÁngelRíos escucha y soprende

消息源中的特定行显示:

主题:=?ISO-8859-1?Q?=C1ngel?= =?ISO-8859-1?Q?R=EDos?= escucha y sorprende

(半完整标题):

Delivered-To: me@gmail.com
Received: {elided}
Return-Path: <return@path>
Received: {elided}
Received: (qmail 23734 invoked by uid 48); 18 Aug 2009 13:51:14 -0000
Date: 18 Aug 2009 13:51:14 -0000
To: "Adriano" <me@gmail.com>
Subject: =?ISO-8859-1?Q?=C1ngel?= =?ISO-8859-1?Q?R=EDos?= escucha y sorprende
MIME-Version: 1.0
From: {elided}
X-Mailer: PHP
X-Lista: 1290
X-ID: 48163
Content-Type: text/html; charset="ISO-8859-1"
Content-Transfer-Encoding: quoted-printable
Message-ID: <kokrte.rpq06m@example.com>

编辑:

该应用程序使用旧版本的 Html Mime Mail 来准备邮件,我会尝试升级到较新的版本。无论如何,这是对主题进行编码的函数:

/**
* Function to encode a header if necessary
* according to RFC2047
*/
function _encodeHeader($input, $charset = 'ISO-8859-1')
{
preg_match_all('/(\w*[\x80-\xFF]+\w*)/', $input, $matches);
foreach ($matches[1] as $value) {
$replacement = preg_replace('/([\x80-\xFF])/e', '"=" . strtoupper(dechex(ord("\1")))', $value);
$input = str_replace($value, '=?' . $charset . '?Q?' . $replacement . '?=', $input);
}

return $input;
}

这是对主题进行编码的代码:

if (!empty($this->headers['Subject'])) {
$subject = $this->_encodeHeader($this->headers['Subject'],
$this->build_params['head_charset']);
unset($this->headers['Subject']);
}

总结

问题是,事实上,在上述情况下,程序并未对空间进行编码。 The accepted answer解决了我的问题,经过轻微修改(在该答案的评论中提到),因为安装的 PHP 版本不支持特定的实现细节。

最终答案

虽然接受的答案确实解决了问题,但我们发现它与数千封电子邮件相结合,正在吞噬服务器上的所有可用内存。查看了这个邮件框架原开发者的网站,发现功能已经更新为:

function _encodeHeader($input, $charset = 'ISO-8859-1') {
preg_match_all('/(\w*[\x80-\xFF]+\w*)/', $input, $matches);
foreach ($matches[1] as $value) {
$replacement = preg_replace('/([\x80-\xFF])/e', '"=" . strtoupper(dechex(ord("\1")))', $value);
$input = str_replace($value, $replacement , $input);
}
if (!empty($matches[1])) {
$input = str_replace(' ', '=20', $input);
$input = '=?' . $charset . '?Q?' .$input . '?=';
}
return $input;
}

巧妙地解决了问题并保持在内存限制之下。

最佳答案

您还需要对中间的空格进行编码(请参阅 RFC 2047 ):

(=?ISO-8859-1?Q?a?= =?ISO-8859-1?Q?b?=)     (ab)

White space between adjacent 'encoded-word's is not displayed.

[…]

(=?ISO-8859-1?Q?a_b?=)                      (a b)

In order to cause a SPACE to be displayed within a portion of encoded text, the SPACE MUST be encoded as part of the 'encoded-word'.

(=?ISO-8859-1?Q?a?= =?ISO-8859-2?Q?_b?=)    (a b)

In order to cause a SPACE to be displayed between two strings of encoded text, the SPACE MAY be encoded as part of one of the 'encoded-word's.

所以应该这样做:

Subject: =?ISO-8859-1?Q?=C1ngel=20R=EDos?= escucha y sorprende

编辑 试试这个功能:

function _encodeHeader($str, $charset='ISO-8859-1')
{
$words = preg_split('/(\s+)/', $str, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
$func = create_function('$match', 'return $match[0] === " " ? "_" : sprintf("=%02X", ord($match[0]));');
$encoded = false;
foreach ($words as $key => &$word) {
if (!ctype_space($word)) {
$tmp = preg_replace_callback('/[^\x21-\x3C\x3E-\x5E\x60-\x7E]/', $func, $word);
if ($tmp !== $word) {
if (!$encoded) {
$word = '=?'.$charset.'?Q?'.$tmp;
} else {
$word = $tmp;
if ($key > 0) {
$words[$key-1] = preg_replace_callback('/[^\x21-\x3C\x3E-\x5E\x60-\x7E]/', $func, $words[$key-1]);
}
}
$encoded = true;
} else {
if ($encoded) {
$words[$key-2] .= '?=';
}
$encoded = false;
}
}
}
if ($encoded) {
$words[$key] .= '?=';
}
return implode('', $words);
}

关于php - 电子邮件主题分隔符中的重音词 - 我该如何阻止它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1294066/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com