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。 它的编码应该和 mb_internal_encoding() 一样。

charset

charset 指定了 str 的字符集名。 其默认值由当前的 NLS 设置(mbstring.language)来确定。

transfer_encoding

transfer_encoding 指定了 MIME 的编码方案。 它可以是 "B"(Base64)也可以是 "Q"(Quoted-Printable)。 如果未设置,将回退为 "B"

newline

newline 指定了 EOL(行尾)标记,使 mb_encode_mimeheader() 执行了一个换行(» RFC 文档中规定,超过长度的一行将换成多行,当前该长度硬式编码为 74 个字符)。 如果没有设定,则回退为 "\r\n" (CRLF)。

indent

首行缩进(header 里 string 前的字符数目)。

返回值

转换后的字符串版本以 ASCII 形式表达。

更新日志

版本 说明
8.3.0 使用 Quoted-Printable 编码时,不再丢弃 NUL(0)字节, 而是编码为 =00
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-?=" <kru@gtinn.mon>

注释

注意:

这个函数没有设计成据更高级上下文的中断点来换行(单词边界等)。 这个特性将导致意外的空格可能会让原始字符串看上去很乱。

参见

添加备注

用户贡献的备注 10 notes

up
8
stormflyCUT at hyh dot pl
19 years ago
Some solution for using national chars and have problem with UTF-8 for example in mail subject. Before you use mb_encode_mimeheader with UTF-8 set mb_internal_encoding('UTF-8').
up
1
nigrez at nius dot waw dot pl
19 years ago
True, function is broken (PHP5.1, encoding from UTF-8 with pl_PL charset). Below is about 15% faster version of proposed _mb_mime_encode. Also it has header more like othe mb_* functions and doesn't trigger any errors/warnings/notices.<?phpfunction 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;}?>
up
2
gullevek at gullevek dot org
22 years ago
Read this FIRST: http://bugs.php.net/bug.php?id=23192 because mb_encode_mimeheaders is BUGGY!a work around for the multibyte broken error for too long subjects for ISO-2022-JP:$pos=0;$split=36; // after 36 single bytes characters, if then comes MB, it is brokenwhile ($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;is not the best, but it works
up
2
Anonymous
16 years ago
I could not find a PHP function to MIME encode the name for a n email address.

Input   = "Karl Müller<kmueller@gmx.de>"
Output = "Karl%20M%FCller<kmueller@gmx.de>"

I wrote it on my own:

<?php
// required to encode names in email addresses    
// replace " " with "%20"
// replace "ü" with "%FC" 
// replace "%" with "%25"      etc....
// Use "%" as Delimiter for MIME
// Use "=" as Delimiter for Quoted Printable
// Input string must be UTF8 encoded
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 not allowed
        {
            $Out .= "?";
        }
        else if ($Chr == " " || $Chr == $Delimiter || $Asc > 127) 
        {
            $Out .= $Delimiter . strtoupper(bin2hex($Chr));
        }
        else $Out .= $Chr;
    }
    return $Out;
}
?>
up
1
tokul at users dot sourceforge dot net
17 years ago
mb_encode_mimeheader() depends on correct mbstring.internal_encoding setting. It tries to convert $str from internal encoding to $charset. If you ignore mbstring internal encoding, function might encode strings incorrectly even when $str character set matches $charset
up
1
gullevek at gullevek dot org
19 years ago
My first post was around 2003, and still the mb_mime_header is broken. It is *NOT* usable with longer subjects, and mostly unusable with anything else than japanese.iwakura at junx dot org is also not working for me, it produces also some gargabe.I updated my old function (the one I posted 2003) and I tested it with overlong subjects in UTF-8, ISO-2022-JP (japanese), GB2312 (simplified chinese) and EUC-KR (korean) and I got readable results in thunderbird, mail.app, outlook, etc.<?phpfunction _mb_mime_encode($string, $encoding){    $pos = 0;    // after 36 single bytes characters if then comes MB, it is broken    // but I trimmed it down to 24, to stay 100% < 76 chars per line    $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;}?>
up
0
paravoid
19 years ago
If mb_ version doesn't work for you in MIME-B mode:function encode_mimeheader($string, $charset=null, $linefeed="\r\n") {    if (!$charset)        $charset = mb_internal_encoding();    $start = "=?$charset?B?";    $end = "?=";    $encoded = '';    /* Each line must have length <= 75, including $start and $end */    $length = 75 - strlen($start) - strlen($end);    /* Average multi-byte ratio */    $ratio = mb_strlen($string, $charset) / strlen($string);    /* Base64 has a 4:3 ratio */    $magic = $avglength = floor(3 * $length * $ratio / 4);    for ($i=0; $i <= mb_strlen($string, $charset); $i+=$magic) {        $magic = $avglength;        $offset = 0;        /* Recalculate magic for each line to be 100% sure */        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;    }    /* Chomp the first space and the last linefeed */    $encoded = substr($encoded, 1, -strlen($linefeed));    return $encoded;}
up
0
chappy at citromail dot hu
19 years ago
In countries where there's non-us ASCII, it's a very good example, for sending mail: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');It creates a 7bit string
up
-1
iwakura at junx dot org
19 years ago
i think mb_encode_mimeheader still have bug. here is sample code: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 {                                // multibyte            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);}is not the best, but it works
up
-3
mortoray at ecircle-ag dot com
20 years ago
At least for Q encoding, this function is unsafe and does not encode correctly. Raw characters which appear as RFC2047 sequences are simply left as is.Ex:mb_encode_mimeheader( '=?iso-8859-1?q?this=20is=20some=20text?=' );returns '=?iso-8859-1?q?this=20is=20some=20text?='The exact same string, which is obviously not the encoding for the source string.  That is, mb_encode_mimeheader does not do any type of escaping.That is, the following condition is not always true:    mb_decode_mimeheader( mb_encode_mimeheader( $text ) ) == $text
To Top