电子邮件主题分隔符间距中的重音单词 - 如何阻止这种情况?

2023-12-26

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

安赫尔·里奥斯·埃斯库查·索普伦德

显示(至少通过 gmail 和 Lotus Notes)为

AngelRíos escucha y sorprende

消息源中的特定行显示:

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

(半完整标题):

Delivered-To: [email protected] /cdn-cgi/l/email-protection
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" <[email protected] /cdn-cgi/l/email-protection>
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: <[email protected] /cdn-cgi/l/email-protection>

EDIT:

该应用程序使用旧版本的 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']);
}

Wrap-up

问题在于,程序确实没有对上述情况下的空间进行编码。接受的答案 https://stackoverflow.com/questions/1294066/accented-words-in-email-subject-break-spacing-how-do-i-stop-this/1294391#1294391经过轻微修改(在该答案的评论中提到)后解决了我的问题,因为安装的 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 https://www.rfc-editor.org/rfc/rfc2047#section-8):

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

不显示相邻“编码字”之间的空白。

[…]

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

为了使空格显示在编码文本的一部分中,必须将空格编码为“编码字”的一部分。

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

为了使空格显示在两个编码文本字符串之间,空格可以被编码为“编码字”之一的一部分。

所以应该这样做:

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

Edit试试这个功能:

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);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

电子邮件主题分隔符间距中的重音单词 - 如何阻止这种情况? 的相关文章

随机推荐

  • 添加产品时,WooCommerce 将追加销售产品添加到购物车

    我正在尝试在我的 WooCommerce 主题中实现自定义追加销售功能 当用户添加产品时 我需要将额外的产品 追加销售 添加到其购物车 这意味着我必须向产品添加一个额外的参数 该参数允许我获取产品 追加销售的关系 并在从购物车中删除产品时删
  • 每月第一天的工作日

    我需要获取该月第一天的工作日 例如 对于当前月份 2013 年 9 月 第一天是星期日 首先 获取当月的第一天 例如 NSDate today NSDate date NSCalendar gregorian NSCalendar allo
  • 尝试更新测试版时 Google Play 出现错误

    当我尝试将新的 apk 上传到我的 beta 频道时 我收到此错误 Errors 在开始推出此版本之前解决这些错误 您无法推出此版本 因为它不允许任何现有用户升级到新添加的 APK 在我的 alpha 频道中 女巫的更新频率要高得多 我可以
  • Matplotlib条形图不绘制边框/边缘

    我的条形图有这个代码 ax1 plt subplot2grid 1 1 0 0 ax1 bar edges2 Nnorm width 0 02 edgecolor green linewidth 20 我认为这应该使我的条形图具有绿色边缘
  • 在酸洗 numpy 数组的子类时保留自定义属性

    我创建了 numpy ndarray 的子类如下numpy 文档 http docs scipy org doc numpy user basics subclassing html 特别是 我有添加了自定义属性 http docs sci
  • 在子组件 React Native 中关闭模式

    我有两个本机组件 我无法从我的子组件中关闭模式 ListTrips 家长 ModalAddTrip 子级 ListTrips js import ModalAddTrip from ModalAddTrip this state isMod
  • Objective C 阻止异步回调和错误访问

    我有一个严重的疑问 假设以下场景 你有一个UIViewController在屏幕上 例如 应用程序使用块作为回调来启动后端调用 您使用 自我 代理来防止保留循环 用户点击 返回 然后UIViewController被释放 迟早 回调块会被执
  • Objective-C enumerateObjectsUsingBlock 与快速枚举?

    以下两种方法的优点和缺点是什么 使用块枚举 https developer apple com documentation foundation nsarray 1415846 enumerateobjectsusingblock lang
  • android错误:删除片段时“提交已调用”

    我想实现一个有片段的活动 当我点击 Fragment1 时 Fragment2 被调用 当我点击 Fragment2 时 Fragment2 应该从屏幕上删除 我通过在 onCreateView 中调用 Fragment2 LinearLa
  • Visual Studio Team Services - 构建失败,定义错误?

    我从事一个项目已经有一段时间了 现在我想使用 Visual Studio Team Services 在本地 Visual Studio 中的构建不会给出错误 并且应用程序按预期工作 我已将此工作代码签入 VSTS 因此它位于存储库中并且可
  • 计数返回空白而不是 0

    今天是个好日子 这是我的代码 SELECT Expired Item DateName mm DATEADD MM 4 AE fld LOAN as Month COUNT PIT fld ID COUNT SUM PIT fld GRAM
  • Android 上的 kivy/Python 缺少 Unicode 编解码器?

    我有一个在 kivy 下运行的程序 它在 Windows 上运行良好 但在 Android 上打开文件失败 两个平台上都是 1 8 0 奇怪的是 当我明确要求 utf 8 时 错误消息表明它正在尝试解码 ASCII 而且该文件中的任何位置都
  • 如何解压和打包pkg文件?

    我有一个由 Install Maker for Mac 创建的 pkg 文件 我想替换 pkg 中的一个文件 但我必须在Linux系统下执行此操作 因为这是下载过程的一部分 当用户开始下载文件时 服务器必须替换 pkg 中的一个文件 我有一
  • 编译 gtkmm 时出现问题

    操作系统 Fedora 14 编译器 g GCC 4 5 1 20100924 红帽 4 5 1 4 我通过 yum 从存储库安装了 gtkmm24 devel 为了确保安装按计划进行 我决定尝试页面上的示例之一 include
  • Oracle 中的动态表分区

    我正在为我的应用程序构建一个数据库存储 该存储由一个具有巨大数据量 数亿条记录 的表组成 我计划在日期字段上建立索引 因为我将不时地对给定时间段内的所有记录进行批量恢复 例如 检索第二天的所有记录 午夜 由于记录数量巨大并且性能是该系统中的
  • 递归地 (?) 将 LINQ 谓词组合成单个谓词

    编辑 我问错了问题 real我遇到的问题已经结束将 LINQ to SQL 谓词组合成单个谓词 https stackoverflow com questions 3782940 compose linq to sql predicates
  • 在 OS X 上以 32 位模式使用 virtualenv 运行非系统 Python

    简短的问题使用 virtualenv virtualenvwrapper 是否可以添加前缀python调用链接到特定的虚拟环境 背景我想使用多个虚拟环境已安装酿造 https github com mxcl homebrewPython 2
  • 如何从 Kotlin DSL build.gradle 中的所有依赖项中排除库?

    我开始迁移build gradle 时髦 到build gradle kts Kotlin DSL 事情是这样的com google common util concurrent ListenableFuture from com goog
  • Netbeans:自动格式 - 防止变量赋值时出现空格格式

    我更喜欢这样的格式化作业 foo bar long foo bar 而不是这个 foo bar long foo bar 然而 Netbeans 在使用自动格式时使用后者 有人知道如何解决这个问题吗 这个问题已经发布三年了 但我认为它非常有
  • 电子邮件主题分隔符间距中的重音单词 - 如何阻止这种情况?

    我们有一个自定义的 php 电子邮件营销应用程序 还有一个有趣的问题 如果邮件的主题行包含带有重音符号的单词 则会 吞掉 该单词与下一个单词之间的空格 示例 短语 安赫尔 里奥斯 埃斯库查 索普伦德 显示 至少通过 gmail 和 Lotu