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=”あ美乳”>のおまじないを入れる以外に良い方法があったら教えて下さい。

回答の条件
  • URL必須
  • 1人2回まで
  • 登録:
  • 終了:--
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答5件)

id:accessmania No.1

回答回数62ベストアンサー獲得回数0

ポイント36pt

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

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

id:EPP

駄目でした。

ブラウザは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で送ってくるという保障もないので頭が痛いです。

2005/08/16 15:33:08
id:meguro0906 No.2

回答回数9ベストアンサー獲得回数0

ポイント36pt

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

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

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

id:EPP

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

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

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

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

2005/08/16 16:03:08
id:accessmania No.3

回答回数62ベストアンサー獲得回数0

ポイント36pt

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では、不具合?らしきものがあるようですが、パッチを適用することにより、改善されています。


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

id:EPP

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

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

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

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

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

2005/08/16 16:46:52
id:namiheikun No.4

回答回数75ベストアンサー獲得回数6

ポイント36pt

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

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

print $data;

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

id:EPP

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

2005/08/16 16:48:13
id:abunakunai No.5

回答回数26ベストアンサー獲得回数3

ポイント36pt

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にするのが個人的には好きです。

id:EPP

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

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

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

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

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

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

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

2005/08/16 18:16:42

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません