WebサイトでPHP + JSON で日本語の出力しているのですが

うまく表示できているのですが、疑問点があるので質問させてください。

PHP側の文字コードの設定は
internal_encoding:euc-jp
http_output:sjis
HTML側で
<meta charset=Shift-JIS>
で表示しています。

処理内容主な流れは
・サーバー側でEUC_JPのデータをUTF-8に文字コード変換
・json_encode()でjsonデータに変換して、echo $jsondata;
・JS側で受け取ってjQuery.parseJSON()でオブジェクトを取得してそのまま表示させています。

疑問点ですが、サーバー側でUTF-8に変換したデータが自動的にSJISに変換されているように見えるのですが、
どのタイミングでSJISに変換されてるんでしょうか。
また自動的に変換されているのであれば、SJISへの変換を明示的に指定するような記述を入れた方が良いような気がするのですが、どうなんでしょうか。

よろしくお願いします。

回答の条件
  • 1人5回まで
  • 登録:
  • 終了:2013/06/17 18:13:00
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:vow No.2

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

ポイント50pt

最近のウェブブラウザであれば例外なく、JavaScriptエンジンからドキュメントデータを読み書きする際に、ドキュメントデータのエンコードにあわせて自動変換されます。だから気がつかないのです。

以下のhtmlをいろいろな文字コードで保存して実行してみればわかるかと。何で保存していても、JavaScriptからは同じUTFのコードで見えます。

<html><head>
<script language=JavaScript>
function dump(){
  S=document.getElementById('dumpTarget').firstChild.data.toString();
  D=[];
  for (i=0;i<S.length;++i) D.push(S.charCodeAt(i).toString(16));
  alert(D);
}
</script></head><body onload="dump()">
<p id="dumpTarget"></p>
</body></html>

追記: 念のため — 厳密に言うならば、JavaScript エンジン上のStringの文字コードは常に UTF-16 です (ECMAScriptの規格でそう定められている)。ですので、サーバから UTF-8 で来たjsonデータが、ブラウザ側の XMLHttpRequest を通過する際に UTF-16 に変換されていて、それがさらにDOM経由でドキュメントに読み書きする際にドキュメントのエンコードに変換される、という流れになります。いずれにせよ JavaScript エンジンを出入りする際のエンコード変換は、おおむね仕様に定められた通りに自動的かつ強制的に行われるものなので、手動で何かする余地も必要もありません。

他1件のコメントを見る
id:Lhankor_Mhy

 横からすみません。
 
 サンプルコード試してみましたが、Chromeは文字コードが指定されていないHTMLを開く時には前回と同じエンコードをするようですね。おそらく文字化けしているはず。
 ですから「自動判別でs-jis表示」→「ソースコードをeucに変更」→「リロードしてもs-jis表示」となっているようです。
 エンコードを確認しながら試してみるとよろしいのではないでしょうか。

2013/06/17 17:30:33
id:timestep

なるほど。metaタグで文字コードを指定しながら確認したところ
すべて同じコードになるのを確認できました。ありがとうございます。

2013/06/17 18:11:15

その他の回答3件)

id:holoholobird No.1

回答回数574ベストアンサー獲得回数104

internal_encoding:euc-jp
http_output:sjis

これでは、内部エンコーディングをEUC-JPにして、httpの出力をSJISに設定しているように見受けられます。
従ってサーバ内ではEUC-JPをSJISにする処理が行われるだけで、UTF-8は処理に関係ないでしょう。

id:timestep

JSONデータUTF-8にサーバー側で変換しています。これも最終的にSJISで出力されています。
聞きたいのはこのデータがどのタイミングで変換されているか、なのですが。

2013/06/17 12:53:30
id:Lhankor_Mhy

UTF-8は処理に関係ないでしょう。

それは勘違いだと思います。

この関数は、UTF-8 エンコードされたデータでのみ動作します。

PHP: json_encode - Manual
2013/06/17 12:57:55
id:vow No.2

回答回数21ベストアンサー獲得回数9ここでベストアンサー

ポイント50pt

最近のウェブブラウザであれば例外なく、JavaScriptエンジンからドキュメントデータを読み書きする際に、ドキュメントデータのエンコードにあわせて自動変換されます。だから気がつかないのです。

以下のhtmlをいろいろな文字コードで保存して実行してみればわかるかと。何で保存していても、JavaScriptからは同じUTFのコードで見えます。

<html><head>
<script language=JavaScript>
function dump(){
  S=document.getElementById('dumpTarget').firstChild.data.toString();
  D=[];
  for (i=0;i<S.length;++i) D.push(S.charCodeAt(i).toString(16));
  alert(D);
}
</script></head><body onload="dump()">
<p id="dumpTarget"></p>
</body></html>

追記: 念のため — 厳密に言うならば、JavaScript エンジン上のStringの文字コードは常に UTF-16 です (ECMAScriptの規格でそう定められている)。ですので、サーバから UTF-8 で来たjsonデータが、ブラウザ側の XMLHttpRequest を通過する際に UTF-16 に変換されていて、それがさらにDOM経由でドキュメントに読み書きする際にドキュメントのエンコードに変換される、という流れになります。いずれにせよ JavaScript エンジンを出入りする際のエンコード変換は、おおむね仕様に定められた通りに自動的かつ強制的に行われるものなので、手動で何かする余地も必要もありません。

他1件のコメントを見る
id:Lhankor_Mhy

 横からすみません。
 
 サンプルコード試してみましたが、Chromeは文字コードが指定されていないHTMLを開く時には前回と同じエンコードをするようですね。おそらく文字化けしているはず。
 ですから「自動判別でs-jis表示」→「ソースコードをeucに変更」→「リロードしてもs-jis表示」となっているようです。
 エンコードを確認しながら試してみるとよろしいのではないでしょうか。

2013/06/17 17:30:33
id:timestep

なるほど。metaタグで文字コードを指定しながら確認したところ
すべて同じコードになるのを確認できました。ありがとうございます。

2013/06/17 18:11:15
id:Lhankor_Mhy No.3

回答回数814ベストアンサー獲得回数232

ポイント50pt

モノを見てないので憶測で書きますが、JavaScriptでDOM操作を行った時にブラウザによって、だと思います。
JSONの出力はutf-8になってるかと思います。
JavaScriptとJSONの文字コードはunicodeですから、それ以前でs-jisに変換される理由がないです。

id:timestep

ブラウザのようですね。ありがとうございます

2013/06/17 14:34:30
id:dawakaki No.4

回答回数797ベストアンサー獲得回数122

http_output:sjis と設定されているので、SJISでhttp送信されます。
http://www.php.net/manual/ja/mbstring.configuration.php#ini.mbstring.http-output

http出力する直前に文字コード変換が起きます。
echoやprintなど出力関数は問いません。http出力する直前に変換されます。

他1件のコメントを見る
id:dawakaki

http_output が sjis に設定されており、
output_handler が mb_output_handler に設定されており、
http 出力が text/html であるとき(echo関数ではそうなる)、
サーバ側でSJISに自動変換されます。
http://lets.postgresql.jp/documents/tutorial/with_php/utf8_as_int_enc/

2013/06/17 18:56:38
id:timestep

今回の場合、サーバー側ではinternal_encodingであるEucJPをSJISに変換してるのであって
UTF8のJSONデータについてはサーバー側では変換してないようです。
echoしてるJSONデータはUTF8したものがUnicodeに変換されたデータで、そのタイミングでは変換されていないということのようです。Unicodeのままブラウザは受け取ってるようです

2013/06/19 10:36:34

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

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

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

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

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