用户评论:
[#1]
Anonymous [2009-04-11 18:19:35]
I could not find a PHP function to MIME encode the name for a n email address.
Input = "Karl M??ller"
Output = "Karl%20M%FCller"
I wrote it on my own:
// 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 encodedpublic static functionEncodeMime($Text,$Delimiter)
{$Text=utf8_decode($Text);$Len=strlen($Text);$Out="";
for ($i=0;$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;
}?>
[#2]
tokul at users dot sourceforge dot net [2008-03-30 04:26:36]
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
[#3]
chappy at citromail dot hu [2006-06-05 04:33:59]
I found a bad function.
{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;
}?>
This function should be used:
{$m=preg_match_all('/(\w*[\x80-\xFF]+\w*)/',$input,$matches);
if($m)$input=mb_encode_mimeheader($input,$charset,'Q');
return$input;
}?>
[#4]
stormflyCUT at hyh dot pl [2006-05-05 04:41:46]
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').
[#5]
paravoid [2006-01-01 17:58:23]
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 = '';
$length = 75 - strlen($start) - strlen($end);
$ratio = mb_strlen($string, $charset) / strlen($string);
$magic = $avglength = floor(3 * $length * $ratio / 4);
for ($i=0; $i <= mb_strlen($string, $charset); $i+=$magic) {
$magic = $avglength;
$offset = 0;
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;
}
[#6]
nigrez at nius dot waw dot pl [2005-12-13 15:42:26]
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.
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;
}?>
[#7]
gullevek at gullevek dot org [2005-11-06 17:29:18]
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.
{$pos=0;// after 36 single bytes characters if then comes MB, it is broken
// but I trimmed it down to 24, to stay 100%
while ($pos
{$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;
}?>
[#8]
chappy at citromail dot hu [2005-10-28 23:14:36]
[#9]
iwakura at junx dot org [2005-09-15 23:35:15]
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
$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 "
";
//print_r($string_array);
//echo "";
foreach ($string_array as $key => $value) {
$value = mb_convert_encoding($value, $encoding);
$string_array[$key] = mb_encode_mimeheader($value, $encoding);
}
//echo "
";
//print_r($string_array);
//echo "
";return implode("", $string_array);
}
is not the best, but it works
[#10]
mortoray at ecircle-ag dot com [2005-03-15 01:19:59]
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
[#11]
gullevek at gullevek dot org [2003-07-30 00:02:10]
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 broken
while ($pos
{
$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
[#12]
masataka [2003-04-12 07:46:20]
second parameter 'charset' is character encoding name, but default must be UTF-8 on PHP4.3.1.