php mb_send_mail,PHP: mb_send_mail - Manual

As others say, mb_encode_mimeheader() seems to have a bug with JIS(ISO-2022-JP) encording. Token indicating start and end of multibyte char is inserted only before start of encoding and after the all.

We need the tokens at start and end of *all* encoded-text.

# PHP 4.3.2

So, we needs some workaround.

The post by "gordon at kanazawa-gu dot ac dot jp" seems to work well, but it doesn't. JIS nees some special tokens and base64_encode does'nt output them, so the code cannot used.

The post "RE: N03L in Japan", which simply splitting words in eash 10 chars is good enough in most case, there are some problem left. When there are some splited parts starting with ascii chars, 1 additional space will be inserted.

# RFC2047 only say within 76 words, shorter is not bad.

Additionally, thought it is really rare case, when we use "=?charset?" as literal string, we have to escape them.

# Some mailer can actually send this without escape and header will be broken. :(

Now, a little non-smart but maybe more accurate code is below function. I tested only with ISO-2022-JP, only in costomized phpBB2.0.5, only some cases.

As far as my test this code worked well, but I'm not sure.

# $str: source text

# $indent: ex. for "Subject: " header, give 9 and first line will be shorter than 76-1-9=66

# $encoding: source text encoding

# $mail_encoding: $str will be converted into this before base64 encode

function encode_mimeheader($str, $indent = 0, $encoding = 'utf-8', $mail_encoding = 'iso-2022-jp')

{

$start_delimiter = strtoupper("=?$mail_encoding?B?");

$start_pattern   = strtoupper("=\\?$mail_encoding\\?B\\?");

$end_delimiter   = '?=';

$str = mb_convert_encoding($str, $mail_encoding, $encoding);

$length  = mb_strlen($str, $mail_encoding);

$max_part_length = 20; // enough short in most case (you can change this default value)

for ($i=0, $index=0; $index

$part_length = $max_part_length;

$s = mb_substr($str, $index, $part_length, $mail_encoding);

// workaround for literally used start delimiter (without below, subject may break)

// note: mb_encode_mimeheader() don't encode ascii including start delimiter

if (preg_match('/^' . $start_pattern . '/i', $s))

{

$lines[$i] = $start_delimiter . base64_encode($start_delimiter) . "?=";

$index += strlen($start_delimiter);

continue;

}

$lines[$i] = mb_encode_mimeheader($s, $mail_encoding);

while (strlen($lines[$i]) > 76-1 - ($i?0:$indent)) { // max par line - first space - indent (first line only)

$part_length = floor($part_length * (76-1 - ($i?0:$indent)) / strlen($lines[$i])); // at least 1 decrement

$s = mb_substr($str, $index, $part_length, $mail_encoding);

$lines[$i] = mb_encode_mimeheader($s, $mail_encoding);

}

// workaround for starting new line with ascii (without below, 1 space may cut in)

// note: mb_encode_mimeheader() starts encode after encounterring multibyte char

if ($i > 0 && !preg_match('/^' . $start_pattern . '/i', $lines[$i]))

{

$p = strpos($lines[$i], $start_delimiter); //never 0 (false when not found)

$p = $p ? $p : strlen($lines[$i]);

$lines[$i] = $start_delimiter . base64_encode(substr($lines[$i], 0, $p)) . "?=";

$part_length = $p;

}

$index += $part_length;

}

$str = join("\r\n ", $lines); // RFC 2047,822 say newline must be ^\r\n, not only\n

return $str;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值