• ベストアンサー

CGIを作っています。渡されて来るEncodeがわかりません

ブログ用数式エディタのCGIを作っています。 CGIの呼び出し文字列の処理は、以下なのですが、 $qstr = rawurldecode($_SERVER["QUERY_STRING"] ); $encd = mb_detect_encoding($qstr, 'EUC-JP,SJIS,UTF-8,JIS'); if ($encd != ''){ $expr = mb_convert_encoding($qstr,"SJIS", $encd); Yahooブログ、CocoLog、Biglobe、Hatenaからの呼び出しは、以上でOKなのですが、 Gooブログでは、トンデモないものに変換されてしまいます。 Gooブログを調べると、 <meta http-equiv="Content-Type" content="text/html; charset=euc-jp"> で、Yahooブログも、 <meta http-equiv="content-type" content="text/html; charset=euc-jp"> で同じEncodeと思うのですが、 私のCGIに渡されて来る文字列は、例えば、 式F(ω)=  の場合 Yahooブログでは、 %BC%B0F%28%A6%D8%29=  で euc-jp です。 しかし、 Gooブログでは、 %C3%A5%C2%BC%C2%8FF%28%C3%8F%C2%89%29= です。これは、何というEncodeなのでしょうか? ためしに、 式F(ω)=  を、UTF-8でEncodeしてrawurlencode()すると、 %E5%BC%8FF%28%CF%89%29%3D なので、だいたい %C3%XX と %C2 が余分で、UTFに近いということは わかりました。

質問者が選んだベストアンサー

  • ベストアンサー
  • bm_hiro
  • ベストアンサー率51% (200/388)
回答No.2

ついでなので、判定に使ったソース公開。 ====================================================================== jadge.php ※ ソースはUTF-8で、書いてください。 ====================================================================== <? $DimCode = file("codes.txt"); $a = "式"; $b = "%C3%A5%C2%BC%C2%8F"; foreach($DimCode as $i => $code) { $c = rawurlencode(mb_convert_encoding($a , trim($code))); $jadge = ($b == $c) ? "<font color=red>Bingo!!!</font>" : ""; print "$code :<br>" . $a . "<br>" . $b . "<br>" . $c . "<br>" . $jadge . "<hr>"; } ?> ====================================================================== ====================================================================== codes.txt ※ http://php.net/manual/ja/mbstring.supported-encodings.php 参照 ====================================================================== UCS-4 UCS-4BE UCS-4LE UCS-2 UCS-2BE UCS-2LE UTF-32 UTF-32BE UTF-32LE UTF-16 UTF-16BE UTF-16LE UTF-7 UTF7-IMAP UTF-8 ASCII EUC-JP SJIS eucJP-win SJIS-win ISO-2022-JP JIS ISO-8859-1 ISO-8859-2 ISO-8859-3 ISO-8859-4 ISO-8859-5 ISO-8859-6 ISO-8859-7 ISO-8859-8 ISO-8859-9 ISO-8859-10 ISO-8859-13 ISO-8859-14 ISO-8859-15 byte2be byte2le byte4be byte4le BASE64 HTML-ENTITIES 7bit 8bit EUC-CN CP936 HZ EUC-TW CP950 BIG-5 EUC-KR UHC ISO-2022-KR Windows-1251 Windows-1252 CP866 KOI8-R ======================================================================

morimot703
質問者

お礼

わざわざ、作って頂きありがとうございます。 ちゃんと数式が表示されるようになりました(以下のdtまでをアドレスバーにコピペして下さい) http://cgi.geocities.jp/rhcpf907/fml2tex/?式F(ω)=∫f(t)e^{-iωt}dt 尚、僕のWeb数式表示サービスは、できるだけ、対象ブログやClientを限定したくないので、 以下のようにしました。参考までに、、、 $qstr = rawurldecode($_SERVER["QUERY_STRING"] ); if ( mb_substr('式',0,1,'SJIS') == mb_substr($qstr,0,1,'SJIS') ){    return $qstr; } $encd = mb_detect_encoding($qstr, 'EUC-JP,SJIS,UTF-8,JIS'); if ($encd != ''){    $expr = mb_convert_encoding($qstr,"SJIS", $encd);    if ( mb_substr('式',0,1,'SJIS') == mb_substr($expr,0,1,'SJIS') )   return $expr; } // Gooブログ及び同様のEncodeブログ対策 $qstr2 = utf8_decode($qstr); $encd = mb_detect_encoding($qstr2, 'EUC-JP,SJIS,UTF-8,JIS'); $expr = mb_convert_encoding($qstr2,'SJIS', $encd); if ( mb_substr('式',0,1,'SJIS') == mb_substr($expr,0,1,'SJIS') )   return $expr; return '@EncodeFail';

その他の回答 (3)

  • bm_hiro
  • ベストアンサー率51% (200/388)
回答No.4

#1、#2です。 とりあえず、#2 の jadge.php は タイポでもなんでもなく、素で間違えました。 正しくは、judge.php です。 んで、#3さんのご指摘を元に、俺の mb_internal_encoding() を 見たところ、 「ISO-8859-1」という結果が。。。 な ん で す か こ れ は ? おうふ、なんてこったい。と思い調べました。 wikiによると 砕けた言い方だと Latin-1 だそうです。 うん。よく聞く名前になりました。 Windows、XAMPPの環境だと そうなるのね。と再発見させていただきました。 とりあえず、そんなわけなので、judge.php に mb_internal_encoding("ISO-8859-1"); と書き加えていただくと、UTF-8 が ビンゴします。 んで、質問者さんが受け取った %C3%A5%C2%BC%C2%8FF%28%C3%8F%C2%89%29= を 式F(ω)= に戻す方法は 以下のような感じです。 少なくとも、俺の環境では ちゃんと 元に戻してくれました。 実際、自分でも 良く分かってません。 ================================================== <html> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <body> <? mb_internal_encoding("ISO-8859-1"); $a = "%C3%A5%C2%BC%C2%8FF%28%C3%8F%C2%89%29="; $b = rawurldecode($a); $c = mb_convert_encoding($b , "ISO-8859-1" , "UTF-8"); print "<hr>$a<hr>$b<hr>$c"; ?> </body> </html> ==================================================

  • hrm_mmm
  • ベストアンサー率63% (292/459)
回答No.3

おもしろそうだから、No2のソースを試したけど bingo が出ない!と思って、No1をよく見ると どうやら、internal_encoding が私の予想に反して、eucでもutf8でもsjisですらないことによるようだ。 No2 の $c = rawurlencode(mb_convert_encoding($a , trim($code))); ↓ $c = rawurlencode(mb_convert_encoding($a ,'utf-8', trim($code))); としたら、ASCII, ISO-8859-1, ISO-8859-3 などがヒット つまり、もともとUTF-8なのに、ISO-8859-1かASCIIだと認識して、さらにUTF-8 へ変換してから、urlencodingが行われている。 しかし、これではもとに戻せませんね。 そのデータ送信時の状況は? 1.送信側ページの状態、form 送信なのか、 それとも aリンクのhrefや img srcのurlクエリにきちんとurlencodeしないで、多バイト文字を書き込んでたりする? 2.使ってるブラウザとか form 送信のとき、IEだと、ページの文字コードがutf-8じゃないときも、utf-8に変換した上でurlencodeする。firefoxは、その文字コードのままurlencodeする。 3.それとも送信はAJAXだったりする? JavaScript の encodeURI() や encodeURIComponent() はutf-8変換したうえで、urlencode します。

morimot703
質問者

お礼

>データ送信時の状況は? imgタグです。 多バイト文字を書き込んでたりします(Encodeはブラウザまかせです) というのは、僕のCGIは、「全角数式のTeX表示のWebサービス」 というべきもので、 ブログ内にimgタグで、数式を全角の∫とか∂を、そのまま書いてもらって、それのTeX画像を返すわけです。 (つまり、HPではなく、URLをブラウザで開いて使うものでは、ありません) そんなわけで、imgタグの埋め込み対象のブログやブラウザは、できるだけ 限定したくないのです。 尚、これのメリットは、 Webの数式エディタ(例えば http://www.codecogs.comhttp://www.codecogs.com/components/equationeditor/equationeditor.php ) では、ブログ本文の作成と数式エディタを往ったり来たりせねばならず、その毎に、思考が中断されます。 で、イラがきて、partialとか、直接 打ちたくなるわけです。 だったら、初めから∂と打てればいい、というわけです。 使い方は、 1.Wiki文法の場合(主にYahooブログ)      [[img(h ttp://cgi.geocities.jp/rhcpf907/fml2tex/?XXXXXX)]] 2.imgタグの場合       <img src="h ttp://cgi.geocities.jp/rhcpf907/fml2tex/?XXXXXX" /> として、 XXXXXXの部分に数式を、以下に従って記述するだけです。 http://www.geocities.jp/rhcpf907/kafuka/guest.txt   サンプル: (1) Yahooブログの場合[[img(http://cgi.geocities.jp/rhcpf907/fml2tex/?式F(ω)=∫f(t)e^{-iωt} dt)]]    または <img src="h ttp://cgi.geocities.jp/rhcpf907/fml2tex/?式F(ω)=∫f(t)e^{-iωt} dt" />

  • bm_hiro
  • ベストアンサー率51% (200/388)
回答No.1

<?php /* 正直、理由は分かりません。 なぜか、結果が一致してしまったので、ご報告します。 このスクリプトを UTF-8で 書いて実行すると そのまま 説明文になっています。 この結果にいたるまで 二時間半かかったのは 内緒。 「F」と「=」は エンコードされてなくて、 「%28」と「%29」は 普通のアスキーコードの 「(」と「)」である事は そちらも把握済みだとは思います。 */ //$a = "式"; $a = "ω"; $b = rawurlencode($a); $d = mb_convert_encoding($a , "UTF-8"); $e = rawurlencode($d); print "とりあえず 普通に 「" . $a . "」を rawurlencode() すると 「" . $b . "」<hr>"; print "ところが、元々 UTF-8 で書いたソースの「" . $a . "」を mb_convert_encoding('" . $a . "' , 'UTF-8') して、rawurlencode() すると 「" . $e . "」になる。<hr>"; ?>

関連するQ&A