忍者ブログ

カウンター

プロモーション

カレンダー

12 2025/01 02
S M T W T F S
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

AntinomyMy の実験室

   私のWEBアプリ実験室です!

ブログ内検索

楽天でお買い物

twitter

最新トラックバック

最新コメント

忍者アナライズ

ウェザーニュース

バーコード

本を買う

アクセス解析

Google+

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。


  • 2025/01/19 03:37

mb_convert_encoding もmb_decode_mimeheader も、UTF-8 のソースと内部エンコードでは、euc-jp からUTF-8 へ変換が超苦手みたいだ

PHP の調べ物

忙しいけど、毎回忘れるので、やっぱり今日もメモのブログ

--- --- --- 文字コードの変換と種類、癖について --- --- ---

mb_decode_mimeheaderを正しく使う
ISO-2022-JP をUTF-8 にうまく変換できない、確かにそうだった

頭の中がまとまってないけど、出所だけまずメモ
EUC-JPからUTF8への変換の際にCP51932を使う
↑は興味深かったが、CP51932 へ変換であって、UTF-8 へのダイレクトな変換でなかった、
しかしCP~ とか言う文字コードがどういうものか知れた。

PHPで「EUC-JP」から「UTF-8」への文字コード変換
↑はおみごと!です、結果的にこの方法で回避しました。「abc①Ⅰ㈱あかさたな髙﨑」は
今後の文字化けチェックでずっと使う言葉になりそう。

文字コード(UTF-8,Shift_JIS,EUC-JP,ISO-2022-JP)についての俺的まとめ
↑は文字コードの解釈でとても分かりやすいので残しました。

cp932,cp51932,cp5022x の簡易テスト
↑はCP関係で残しました。


--- --- --- メール送受信時の文字変換のサンプル付きの説明 --- --- ---

mb_encode_mimeheader()の使い方
↑はメール送信前のエンコードの仕方とコードの特徴、癖

PEARで分解したメールの件名が携帯で文字化け
↑はまとめ役が居ないので、この手は微妙だけど、なんとなく載せてみた

mb_decode_mimeheaderの挙動
↑は結構だれもが考えて通る道だと思った、私は最終的に内部エンコードを
何度も変えるのには疑問を覚えたので、mb_decode_mimeheader を使うのを辞めたが
どうしてもとか、苦肉の策とかならこういった発想になると思う、
どちらにしてもメール処理はゴリゴリ書くか、苦肉の策になりそうだけど。

mb_decode_mimeheader()
↑は、そのまた↑と良く似た発想をしている。


--- --- --- 優良なメールデコードサンプル(でも使わなかったorz) --- --- ---

【PHP】mb_decode_mimeheader の代わりになるものを作る(機種依存文字対策)
↑はかなり良さそうで神経質な処理をしている、自信のソースのエンコードが何かや、
内部エンコードがUTF-8 のときに試したかなどがなかった、
実際やってみたけど多分ここまでしない方法もある気がした。
ゴリゴリ書くなら、この辺を基本にして考えてみるのが良いと思えた。

mb_decode_mimeheaderと機種依存文字
↑ISO-2022-JP-MS というものを知った、かなり考えている様であるが、
こちらの環境では梯段の「髙」を変換できなかったので、たぶんニアピンなのかと思って
採用しなかった。

PHP による日本語の文字コード判定スクリプト
↑文字コードの判定についての処理が書かれているが、
でもこれを使わなければいけない程の短い文字列での極度に困った状態に
あったことがないので、今後使うかどうかの参考にしている。

--- --- --- 実際に使ったメール受信でのデコードとパーツを分解して取得する処理 --- --- ---

メール本文を取得して本文を変更する
↑実際にこのサイトの内容の処理を元に改良し、
内部処理そして保存ソースコードもUTF-8 で
内部処理コードをソース上で変換するmb_internal_encoding も使わず変換し、
「abc①Ⅰ㈱あかさたな髙﨑」を文字化けせずに使える関数を作った。

ただし、今回はPEARのMail で処理する部分に
mimeDecode.php(内部のインクルードでPEAR.php と、PEAR5.php)を
使っている。

これら3つのファイルを同一のフォルダに入れて使えば済むので、
そうやってサーバー上に設置してみた。(実際に適当なディレクトリ「pear_Mail」を作っていれてある)



では実際に作ったソース(途中端折ったりしてますし、定数も書いていません、適当に直してね!)
以下↓↓↓ ↓↓↓ ↓↓↓
------------------------------------------------------------------------------------------------------------------------
// このファイルの文字コードはUTF-8用に作られています、サーバーのメールデーモンがメールをトリガにこのファイルを処理するのを想定しています
mb_internal_encoding("UTF-8");
//echo mb_language();
mb_language('japanese');
//mb_language("uni");
ini_set('mbstring.script_encoding','UTF-8');
//PEAR メールヘッダ解析 メールをメールデーモンからパイプ処理するので、~~~~~~~~~ はフルパスで
require_once(~~~~~~~~~~~'pear_Mail/mimeDecode.php');
//メールソースを標準入力から読み込み
if (php_sapi_name()=="cli") { // ぶっちゃけここは動いていない環境があると思う、適当・・・
while(!feof(STDIN)) {
$source .= file_get_contents(STDIN);
}
} elseif (php_sapi_name()=="cgi") { // ぶっちゃけここは動いていない環境があると思う、適当・・・
$source = file_get_contents('php://stdin');
}else{
$source = file_get_contents('php://stdin');
}
if ($source) {
//解析
$decoder = new Mail_mimeDecode($source);
$params['include_bodies'] = true; //ボディを解析する
$params['decode_bodies']= true; //ボディをコード変換する
$params['decode_headers'] = true; //ヘッダをコード変換する
$structure = $decoder->decode($params);
//送信者のメアドだけ先に欲しかったので、書いているが、必要なければカットして!
if( preg_match( '/<([^>]+)>$/', $headerAndBody['from'], $getFrom )){ $getFrom=$getFrom[1]; }else{$getFrom=$headerAndBody['from'];}
//チェックルーチンだけど、メモで残しているだけ。
// ob_start();
// echo "\n".'$$headerAndBodyのvar_dump'."\n";
// var_dump($headerAndBody);
// echo "\n".'$getFromのvar_dump'."\n";
// var_dump(getFrom);
// $out1 = ob_get_contents();
// ob_end_clean();
//
//// $mailCheckFlag=
// sendMailRapper( //テスト用のmb_send_mail のラッパーを呼び出して実験したりする為に書いたもの
// 'xxxxx@xxxx.xxxxx',
// '【^v^っ】'.$getFrom.'から',
// $out1,
// SYSTEM_MAIL
// );
// if(!$mailCheckFlag){ //メール処理は、失敗したかどうか分からないので、失敗するとファイルが出来て、失敗の文字が増える様にしている
// $fp = fopen(INCLUDE_FUNCTION_DIRECTORY.'_____no_mail_false.txt', 'a+');
// fwrite($fp, print_r('失敗',true));
// fclose($fp);
// }
// $fp = fopen(INCLUDE_FUNCTION_DIRECTORY.'_____headerAndBod.txt', 'a+');
// fwrite($fp, print_r($out1,true));
// fclose($fp);
exit;
function getHeaderAndBody($structure) {
//文字コード検出順番
// $detectEncodingList=array('ASCII','iso-2022-jp-ms','ISO-2022-JP','eucJP-win','UTF-8','SJIS-win','SJIS','EUC-JP','JIS'); //インプットの内容判別、かなり重要な並び
// $headerDetectEncodingList=array('iso-2022-jp' => 'iso-2022-jp-ms', 'shift_jis' => 'sjis-win', 'euc-jp' => 'eucjp-win', 'utf-8' => 'utf-8');
$headerDetectEncodingList=array('iso-2022-jp-ms', 'sjis-win', 'eucjp-win', 'utf-8');
// CP51932 はEUC-JP の仲間らしいが、なぜかたまに失敗して止まるので、やはりeucjp-win を使うのが良いみたいだ
// mb_detect_order($detectEncodingList);
$headerAndBodyArray = array();
//メールヘッダ情報の取得
$headerAndBodyArray['date'] = date("Y-m-d H:i:s", strtotime($structure->headers['date']));
$headerAndBodyArray['from'] = mb_convert_encoding(mb_convert_encoding(mb_convert_encoding($structure->headers['from'], 'eucjp-win', $headerDetectEncodingList), 'sjis-win', 'eucjp-win'), mb_internal_encoding(), 'sjis-win');
$headerAndBodyArray['subject'] = mb_convert_encoding(mb_convert_encoding(mb_convert_encoding($structure->headers['subject'], 'eucjp-win', $headerDetectEncodingList), 'sjis-win', 'eucjp-win'), mb_internal_encoding(), 'sjis-win');
if (strtolower($structure->ctype_primary) == "multipart") {
//複数本文があるメール(本文を1件づつ処理する)
foreach ($structure->parts as $partOneKey => $partOneValue) {
//タイプ
if ($partOneValue->disposition=="attachment") {
//添付ファイル
$headerAndBodyArray[$partOneKey]['attachment'] = array(
'type' => strtolower($partOneValue->ctype_primary)."/".strtolower($partOneValue->ctype_secondary),
'name' => $partOneValue->ctype_parameters['name'],
'binary' => $partOneValue->body
);
} else {
switch (strtolower($partOneValue->ctype_primary)) {
case "image": //HTML本文中の画像
$headerAndBodyArray[$partOneKey]['image'] = array(
'type' => strtolower($partOneValue->ctype_primary)."/".strtolower($partOneValue->ctype_secondary),
'name' => $partOneValue->ctype_parameters['name'],
'cid' => trim($partOneValue->headers['content-id'], "<>"),
'binary' => $partOneValue->body
);
break;
case "text": //テキスト本文の抽出
if ($partOneValue->ctype_secondary=="plain") {
$headerAndBodyArray[$partOneKey]['body'] = trim(mb_convert_encoding(mb_convert_encoding(mb_convert_encoding($partOneValue->body, 'eucjp-win', $headerDetectEncodingList), 'sjis-win', 'eucjp-win'), mb_internal_encoding(), 'sjis-win'));
} else { //HTML本文
$headerAndBodyArray[$partOneKey][$partOneValue->ctype_secondary] = trim(mb_convert_encoding(mb_convert_encoding(mb_convert_encoding($partOneValue->body, 'eucjp-win', $headerDetectEncodingList), 'sjis-win', 'eucjp-win'), mb_internal_encoding(), 'sjis-win'));
}
break;
case "multipart": //マルチパートの中にマルチパートがある場合(MS-OutlookExpressからHTML形式で送信した場合)
$headerAndBodyArray[$partOneKey]['multipart']=getHeaderAndBody($partOneValue);
break;
}
}
}
} elseif (strtolower($structure->ctype_primary) == "text") {
//テキスト本文のみのメール
$headerAndBodyArray['body'] = trim(mb_convert_encoding(mb_convert_encoding(mb_convert_encoding($structure->body, 'eucjp-win', $headerDetectEncodingList), 'sjis-win', 'eucjp-win'), mb_internal_encoding(), 'sjis-win'));
}
return $headerAndBodyArray;
}



------------------------------------------------------------------------------------------------------------------------

さて、忙しいので、メモ書きはこれで終わります。

お粗末でした<_ _>



追伸:

shift-JIS 、SJIS は変換できても、JIS は変換がうまくいってない事が分かった^^;

また、
mb_convert_encoding 関数の ISO-2022-JP と JIS の違い
↑上記で分かったこともあった

 ISO-2022-JP → UTF-8 の変換をする際には、 JIS → UTF-8 の処理を使いまわしているようです。

ということでした。

とりあえず、JISは別の変換を・・・・作らなければ。


拍手[1回]

PR


  • 2013/10/27 19:38

コメント一覧

  • お名前
  • Email

  • コメント

  • Vodafone絵文字 i-mode絵文字 Ezweb絵文字
  • パスワード
[PR]