mb_encode_mimeheader

(PHP 4 >= 4.0.6, PHP 5, PHP 7, PHP 8)

mb_encode_mimeheader对 MIME 标头进行字符串编码

描述

mb_encode_mimeheader(
    string $string,
    ?string $charset = null,
    ?string $transfer_encoding = null,
    string $newline = "\r\n",
    int $indent = 0
): string

使用 MIME 标头编码方案对给定的 string string 进行编码。

参数

string

要编码的 string。它的编码应与 mb_internal_encoding() 相同。

charset

charset 指定 string 所表示的字符集名称。默认值由当前 NLS 设置 (mbstring.language) 确定。

transfer_encoding

transfer_encoding 指定 MIME 编码方案。它应为 "B" (Base64) 或 "Q" (Quoted-Printable)。如果没有给出,则回退到 "B"

newline

newline 指定 mb_encode_mimeheader() 执行折行 (RFC 术语,将超过一定长度的行拆分为多行。长度目前硬编码为 74 个字符) 所使用的 EOL (行结束) 标记。如果没有给出,则回退到 "\r\n" (CRLF)。

indent

第一行的缩进量 (标头中 string 之前的字符数)。

返回值

以 ASCII 表示的 string 的转换版本。

变更日志

版本 描述
8.0.0 charsettransfer_encoding 现在可以为空。

范例

示例 #1 mb_encode_mimeheader() 示例

<?php
$name
= "太郎"; // kanji
$mbox = "kru";
$doma = "gtinn.mon";
$addr = '"' . addcslashes(mb_encode_mimeheader($name, "UTF-7", "Q"), '"') . '" <' . $mbox . "@" . $doma . ">";
echo
$addr;
?>

上面的例子将输出

"=?UTF-7?Q?+WSqQzg-?=" <[email protected]>

注释

注意:

此函数并非设计用于在更高级别的上下文断点 (单词边界等) 处断行。此行为可能会在原始字符串中添加意外的空格,使字符串变得混乱。

参见

添加注释

用户贡献的注释 10 个注释

7
stormflyCUT at hyh dot pl
18 年前
一些使用国家字符并遇到 UTF-8 问题的解决方案,例如在邮件主题中。在使用 mb_encode_mimeheader 与 UTF-8 之前,请设置 mb_internal_encoding('UTF-8')。
1
nigrez at nius dot waw dot pl
18 年前
没错,该函数有故障 (PHP5.1,来自 UTF-8 的编码使用 pl_PL 字符集)。下面是 _mb_mime_encode 的一个速度提升大约 15% 的版本。此外,它还具有类似其他 mb_* 函数的标头,并且不会触发任何错误/警告/通知。

<?php

function mb_mime_header($string, $encoding=null, $linefeed="\r\n") {
if(!
$encoding) $encoding = mb_internal_encoding();
$encoded = '';

while(
$length = mb_strlen($string)) {
$encoded .= "=?$encoding?B?"
. base64_encode(mb_substr($string,0,24,$encoding))
.
"?=$linefeed";

$string = mb_substr($string,24,$length,$encoding);
}

return
$encoded;
}

?>
2
gullevek at gullevek dot org
21 年前
首先阅读:http://bugs.php.net/bug.php?id=23192 因为 mb_encode_mimeheaders 有故障!

针对 ISO-2022-JP 主题过长导致的多字节错误的变通方案

$pos=0;
$split=36; // 在 36 个单字节字符之后,如果随后出现 MB,则会出错
while ($pos<mb_strlen($string,$encoding))
{
$output=mb_strimwidth($string,$pos,$split,"",$encoding);
$pos+=mb_strlen($output,$encoding);
$_string.=(($_string)?' ':'').mb_encode_mimeheader($output,$encoding);
}
$string=$_string;

不是最好的解决方案,但它可以工作
2
Anonymous
15 年前
我找不到任何 PHP 函数来对电子邮件地址的名称进行 MIME 编码。

输入 = "Karl Müller<[email protected]>"
输出 = "Karl%20M%FCller<[email protected]>"

我自己编写了该函数

<?php
// 编码电子邮件地址中的名称所需
// 将 " " 替换为 "%20"
// 将 "ü" 替换为 "%FC"
// 将 "%" 替换为 "%25" 等...
// 使用 "%" 作为 MIME 的分隔符
// 使用 "=" 作为 Quoted Printable 的分隔符
// 输入字符串必须是 UTF8 编码的
public static function EncodeMime($Text, $Delimiter)
{
$Text = utf8_decode($Text);
$Len = strlen($Text);
$Out = "";
for (
$i=0; $i<$Len; $i++)
{
$Chr = substr($Text, $i, 1);
$Asc = ord($Chr);

if (
$Asc > 0x255) // 不允许 Unicode
{
$Out .= "?";
}
else if (
$Chr == " " || $Chr == $Delimiter || $Asc > 127)
{
$Out .= $Delimiter . strtoupper(bin2hex($Chr));
}
else
$Out .= $Chr;
}
return
$Out;
}
?>
1
tokul at users dot sourceforge dot net
16 年前
mb_encode_mimeheader() 依赖于正确的 mbstring.internal_encoding 设置。它尝试将 $str 从内部编码转换为 $charset。如果您忽略 mbstring 内部编码,即使 $str 字符集与 $charset 匹配,函数也可能错误地编码字符串。
1
gullevek at gullevek dot org
18 年前
我的第一篇帖子大约是在 2003 年,mb_mime_header 仍然存在问题。它*无法*用于较长的主题,并且大多数情况下无法与日语以外的任何其他语言一起使用。

iwakura at junx dot org 对我来说也不起作用,它也产生了一些垃圾。

我更新了我的旧函数(我在 2003 年发布的函数),并用 UTF-8、ISO-2022-JP(日语)、GB2312(简体中文)和 EUC-KR(韩语)中的超长主题对其进行了测试,并且我在 Thunderbird、Mail.app、Outlook 等中获得了可读的结果。

<?php

function _mb_mime_encode($string, $encoding)
{
$pos = 0;
// 如果在 36 个单字节字符之后出现 MB,则会出错
// 但我将其缩减到 24,以确保每行 100% < 76 个字符
$split = 24;
while (
$pos < mb_strlen($string, $encoding))
{
$output = mb_strimwidth($string, $pos, $split, "", $encoding);
$pos += mb_strlen($output, $encoding);
$_string_encoded = "=?".$encoding."?B?".base64_encode($output)."?=";
if (
$_string)
$_string .= "\r\n";
$_string .= $_string_encoded;
}
$string = $_string;
return
$string;
}

?>
0
paravoid
18 年前
如果 mb_ 版本在 MIME-B 模式下对您不起作用

function encode_mimeheader($string, $charset=null, $linefeed="\r\n") {
if (!$charset)
$charset = mb_internal_encoding();

$start = "=?$charset?B?";
$end = "?=";
$encoded = '';

/* 每行必须长度 <= 75,包括 $start 和 $end */
$length = 75 - strlen($start) - strlen($end);
/* 平均多字节比率 */
$ratio = mb_strlen($string, $charset) / strlen($string);
/* Base64 的比率为 4:3 */
$magic = $avglength = floor(3 * $length * $ratio / 4);

for ($i=0; $i <= mb_strlen($string, $charset); $i+=$magic) {
$magic = $avglength;
$offset = 0;
/* 重新计算每行的 magic 以确保 100% */
do {
$magic -= $offset;
$chunk = mb_substr($string, $i, $magic, $charset);
$chunk = base64_encode($chunk);
$offset++;
} while (strlen($chunk) > $length);
if ($chunk)
$encoded .= ' '.$start.$chunk.$end.$linefeed;
}
/* 移除第一个空格和最后一个换行符 */
$encoded = substr($encoded, 1, -strlen($linefeed));

return $encoded;
}
0
chappy at citromail dot hu
18 年前
在使用非美式 ASCII 的国家/地区,这是一个很好的发送邮件示例

mb_internal_encoding('iso-8859-2');
setlocale(LC_CTYPE, 'hu_HU');

function encode($str,$charset){
$str=mb_encode_mimeheader(trim($str),$charset, 'Q', "\n\t");
return $str;
}

print encode('the text with spec. chars: &#337; &#368; &#336; &#369;, ?','iso-8859-2');

它创建一个 7 位字符串
-1
iwakura at junx dot org
18 年前
我认为 mb_encode_mimeheader 仍然存在错误。这是一个示例代码

function mb_encode_mimeheader2($string, $encoding = "ISO-2022-JP") {
$string_array = array();
$pos = 0;
$row = 0;
$mode = 0;

while ($pos < mb_strlen($string)) {
$word = mb_strimwidth($string, $pos, 1);
if (!$word) {
$word = mb_strimwidth($string, $pos, 2);
}
if (mb_ereg_match("[ -~]", $word)) { // ascii
if ($mode != 1) {
$row++;
$mode = 1;
$string_array[$row] = NULL;
}
} else { // 多字节
if ($mode != 2) {
$row++;
$mode = 2;
$string_array[$row] = NULL;
}
}
$string_array[$row] .= $word;
$pos++;
}

//echo "<pre>";
//print_r($string_array);
//echo "</pre>";

foreach ($string_array as $key => $value) {
$value = mb_convert_encoding($value, $encoding);
$string_array[$key] = mb_encode_mimeheader($value, $encoding);
}

//echo "<pre>";
//print_r($string_array);
//echo "</pre>";

return implode("", $string_array);
}

不是最好的解决方案,但它可以工作
-3
mortoray at ecircle-ag dot com
19 年前
至少对于 Q 编码而言,此函数不安全,并且无法正确编码。以 RFC2047 序列形式出现的原始字符会直接保留。

例如

mb_encode_mimeheader( '=?iso-8859-1?q?this=20is=20some=20text?=' );

返回 '=?iso-8859-1?q?this=20is=20some=20text?='

完全相同的字符串,这显然不是源字符串的编码。也就是说,mb_encode_mimeheader 不会进行任何类型的转义。

也就是说,以下条件并不总是成立
mb_decode_mimeheader( mb_encode_mimeheader( $text ) ) == $text
To Top