人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

PHPでWebアプリを作成しています。
フォームの入力項目で特定の漢字(琥珀、など)を入力してsubmitし、PHP側でprintで表示させると文字化けしてしまうのですが、これを回避する方法はありますでしょうか?
なおPHPソースはEUC-JPで記述し、HTML出力時にSJISに変換しています。

PHPバージョン4.3.11で、mbstring回りの設定は以下の通りです。
mbstring.detect_order no value
mbstring.encoding_translation On
mbstring.func_overload 0
mbstring.http_input auto
mbstring.http_output SJIS
mbstring.internal_encoding EUC-JP
mbstring.language Japanese
mbstring.script_encoding no value
mbstring.substitute_character no value

<input type=”hidden” value=”あ美乳”>のおまじないを入れる以外に良い方法があったら教えて下さい。

●質問者: EPP
●カテゴリ:コンピュータ
✍キーワード:EUC-JP HTML ON PHP print
○ 状態 :終了
└ 回答数 : 5/5件

▽最新の回答へ

1 ● accessmania
●36ポイント

http://jp.php.net/manual/ja/function.header.php

PHP: header - Manual

header関数でContent-type、charsetを明示してはいかがでしょうか?

header(”Content-type: text/html;charset=Shift-JIS”);

◎質問者からの返答

駄目でした。

ブラウザはIE6とFireFoxでテストしていますが、header関数の指定がなくてもブラウザ側はHTMLのエンコードをShift-JISと認識しています。

またsubmit後のURLを見る限り、両ブラウザとも入力された漢字をShift-JISの文字コードのままurlencodeして送信しています。

ここからは推測になりますが。

PHP側でprint mb_convert_encoding($_REQUEST[’string’],”SJIS”,”EUC-JP”);等としていて通常は正常に動く所を見ると、PHP側はShift-JISで送信された文字列を、文字コードを「自動判別」した上でEUC-JPに変換し、PHPスクリプトに渡しているようです。

おそらくは自動判別の時に、Shift-JIS以外と判定してバグってるんじゃないかと....

#ブラウザが必ずShift-JISで送ってくるという保障もないので頭が痛いです。


2 ● meguro0906
●36ポイント

http://www.shtml.jp/mojibake/sjis_cgi.html

CGIで特定の文字(表・予・申・能など)が文字化けする

php.iniのmagic_quotes_gpc offとしてみてはいかがでしょうか?

◎質問者からの返答

例えば今実際にこちらの環境で化けている「琥珀」は、SJISでは %E0%E6%E0%DF で、EUC-JPでは %E0%E8%E0%E1 です。

%5Cを含まないので異なる問題だと思います。

ともかく、このような問題がある事も覚えておきます。

引き続き回答をお待ちしています。


3 ● accessmania
●36ポイント

http://jp.php.net/manual/ja/function.mb-detect-order.php

PHP: mb_detect_order - Manual

header関数は関係なかったようですね。すみませんm(__)m


mb_detect_orderが現在、「no value」となっていますが、「auto」としてみてはいかがですか?


これでも、化けるようでしたら、下記のURLをご覧下さい。


何度もすみません。

http://ns1.php.gr.jp/pipermail/php-users/2005-April/025814.html

[PHP-users 25298] mb_convert_encoding/mb_detect_encoding について

上記URLを見ますと、php-4.3.11では、不具合?らしきものがあるようですが、パッチを適用することにより、改善されています。


パッチを適用されてみてはいかがでしょうか?

◎質問者からの返答

設定の変更やパッチの適応は最終手段としておきます。現用系を止める訳にはいかないシステムなので....

2番目のURL、非常に参考になりました!

自分の環境の場合、ブラウザ側でShift-JISでsubmitした文字列がPHPスクリプト側ではEUC-JPで取得できるのですが(色々試した結果確定です)、特定の文字列(琥珀、とか)の場合のみ、EUC-JPに変換されずShift-JISのまたわたってきていると解りました。というか、ブラウザから渡された文字コードがEUC-JPだと誤認しているようです。

....というか、文字コードの範囲を考えると、%E0%E6%E0%DFってShift-JISかEUC-JPか自動判別不可能のような....?

引き続き回答をお待ちしております。


4 ● namiheikun
●36ポイント

http://php.s3.to/man/function.mb-convert-encoding.html

mb_convert_encoding

受信側でpostで送られてくるときにEUC-JPで送られてきている為で、

$data = mb_convert_encoding($_POST[’data’],”EUC-JP”,”SJIS”);

print $data;

でSJISに変換されて正常に表示できませんでしょうか?

◎質問者からの返答

3番目の回答に書きましたが、通常はShift-JISでsubmitされたものがPHPスクリプト側ではEUC-JPに変換されて取れるのですが、特定の文字列の場合だけShift-JISのまま取れている、という状況です。


5 ● abunakunai
●36ポイント

http://jp.php.net/manual/ja/function.mb-detect-encoding.php

PHP: mb_detect_encoding - Manual

mbstring.detect_order no value

mbstring.http_input auto


原因はこの2点です。

http_inputがautoなんで文字判定に失敗します。

ここを.htaccessでpassにして、

スクリプト内で

mb_detect_order(’ascii, jis, utf-8, sjis-win, eucjp-win’)

を設定します。

(sjisのがeucよりも使われていると判断して優先させる)

mb_internal_encoding()も設定したほうがよいでしょう。


美乳は使わないらしいですが、上記設定にして

<input type=”hidden” name=”c” value=”美乳”>

$charcode = mb_detect_encoding($_POST[’c’]);

この$charcodeを利用してmb_convert_encoding($_POST[’message’], ’変換したいコード’, $charcode);

とすれば”意図的に”name=cのvalueを変更されない限り正常に変換されます。

mbstring.http_outputもpassにするのが個人的には好きです。

◎質問者からの返答

文字コードの自動判別をSJIS優先にした場合「EUC-JPで文字コードを投げてくるブラウザはないのか?」という点が気になります。

#Unix、Linux用のブラウザが該当しそうです。

お陰さまで色々情報が集まりました。結局、手元で発生した文字化けの原因は2種類あったようです。

・「琥珀」に関して言えば、Shift-JISの「琥珀」の文字コードである %E0%E6%E0%DF に相当するEUC-JPの文字「琅珎」が存在するため、この文字だけを入力されたらSJISかEUC-JPか判別のしようがない。

・「勇」でも化ける箇所があるのですが、これは文字コードを(正しくはEUC-JPなのに)UTF-8と誤認(?これもUTF-8で相当する字が存在するだけかも)している。

まだどう対処するかは決まっていませんが、決めるのに十分な情報は集まったと思いますので、これで質問を終了します。

皆様ありがとうございました。

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ