dポイントプレゼントキャンペーン実施中!

ブログ用数式エディタの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に近いということは
わかりました。

A 回答 (4件)

ついでなので、判定に使ったソース公開。



======================================================================
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-enco … 参照
======================================================================
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
======================================================================
    • good
    • 0
この回答へのお礼

わざわざ、作って頂きありがとうございます。
ちゃんと数式が表示されるようになりました(以下の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';

お礼日時:2010/03/03 12:06

#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>
==================================================
    • good
    • 0

おもしろそうだから、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 します。
    • good
    • 0
この回答へのお礼

>データ送信時の状況は?
imgタグです。
多バイト文字を書き込んでたりします(Encodeはブラウザまかせです)

というのは、僕のCGIは、「全角数式のTeX表示のWebサービス」
というべきもので、
ブログ内にimgタグで、数式を全角の∫とか∂を、そのまま書いてもらって、それのTeX画像を返すわけです。
(つまり、HPではなく、URLをブラウザで開いて使うものでは、ありません)
そんなわけで、imgタグの埋め込み対象のブログやブラウザは、できるだけ
限定したくないのです。
尚、これのメリットは、
Webの数式エディタ(例えば http://www.codecogs.com
http://www.codecogs.com/components/equationedito …
では、ブログ本文の作成と数式エディタを往ったり来たりせねばならず、その毎に、思考が中断されます。
で、イラがきて、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" />

お礼日時:2010/03/03 12:33

<?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>";

?>
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!