phpの文字コード変換で困っています。


utf-8でコーディングしていて、
携帯用のサイトなのでShift-JISに変換して
サイトに出力しようと思っています。

$out = mb_convert_encoding($out, "SJIS", "UTF-8");

のようにしてみて、$outをechoしたのですが、
文字が化けてしまいます。

一応$out内のhtmlのhead部分には
<meta http-equiv="Content-Type" content="text/html; charset=Shift-JIS">
と書いてあります。

utf-8で書いてutf-8で出力するのは問題なかったのですが、
まさかshift-jis変換でハマるとは・・・。

shift-jisでプログラムもタグも書いた方が楽な気がしてきましたが、
PC向けサイトのコードとごっちゃになりそうなので、
なんとかutf-8で書いてshift-jisで出力したいです。

何かミスしていそうなところを
アドバイスして頂けると助かります。

回答の条件
  • 1人5回まで
  • 登録:
  • 終了:2007/07/19 11:27:53
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:studioes No.1

回答回数523ベストアンサー獲得回数61

ポイント100pt

 WebサーバはApacheでしょうか?

 Apacheの場合、httpd.confのAddDefaultCharsetでISO-8859-1がインストールデフォルトで設定されているので、これを無効にしないとヘッダでISO-8859-1が明示されるため、METAよりもこちらが優先されてSJISやEUCは化けることがあります(UTF-8だけは検出されます)

 ソースにBOMが付いていませんか? BOMがあると、UTF-8として認識されるため、SJISをUTF-8として解釈しようとするため、化けることがあります。

id:onigirin

どうもありがとうございます。

xreaサーバーなので、Apacheだと思います。

一応phpのファイルでBOMをつけないで保存してみましたが、

文字化けしてしまいました・・・。

初めの段階で、

$out = mb_convert_encoding($out, "SJIS", "UTF-8");

を書かなければ正常に表示されます。

その場合、

<meta http-equiv="Content-Type" content="text/html; charset=Shift-JIS">

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

としても、正常に表示されます。

文字コードについて、ちょっとわけがわからなくなってます・・・。

2007/07/18 07:27:33

その他の回答5件)

id:studioes No.1

回答回数523ベストアンサー獲得回数61ここでベストアンサー

ポイント100pt

 WebサーバはApacheでしょうか?

 Apacheの場合、httpd.confのAddDefaultCharsetでISO-8859-1がインストールデフォルトで設定されているので、これを無効にしないとヘッダでISO-8859-1が明示されるため、METAよりもこちらが優先されてSJISやEUCは化けることがあります(UTF-8だけは検出されます)

 ソースにBOMが付いていませんか? BOMがあると、UTF-8として認識されるため、SJISをUTF-8として解釈しようとするため、化けることがあります。

id:onigirin

どうもありがとうございます。

xreaサーバーなので、Apacheだと思います。

一応phpのファイルでBOMをつけないで保存してみましたが、

文字化けしてしまいました・・・。

初めの段階で、

$out = mb_convert_encoding($out, "SJIS", "UTF-8");

を書かなければ正常に表示されます。

その場合、

<meta http-equiv="Content-Type" content="text/html; charset=Shift-JIS">

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

としても、正常に表示されます。

文字コードについて、ちょっとわけがわからなくなってます・・・。

2007/07/18 07:27:33
id:Knoa No.2

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

ポイント19pt

HTTPのヘッダじゃないかしら。

httpd.confや.htaccessで制御することもできますが、PHPでやるなら、これ書いてみて。

header( 'Content-type: text/html; charset=UTF-8' );

id:onigirin

どうもありがとうございます。

echoの1行前に入れてみましたが、ダメでした。

$outの前でもダメでした・・・。

$out = mb_convert_encoding($out, "SJIS", "UTF-8");

$out = mb_convert_encoding($out, "UTF-8", "UTF-8");

にすると正常に表示され、

$out = mb_convert_encoding($out, "SJIS", "SJIS");

にすると、だいたい正常に表示されるのですが、

一部の文字、例えば  ) 等が「?」に文字化けしたりしています。

何かくだらないミスをしてそうな気がしてきました・・・。

2007/07/18 08:07:40
id:Bookmarker No.3

回答回数191ベストアンサー獲得回数34

ポイント18pt

charset 名が間違っています。

charset=Shift-JIS

じゃなくて、

charset=Shift_JIS

です。


参考:http://www.iana.org/assignments/character-sets

id:onigirin

どうもありがとうございます。

た・たしかに・・・。

修正してみましたが、表示は変わらずダメでした。

表示したページのソースを見て、

そのHTMLソースをテキストエディタで

文字コードをShift_JISにして読み直すと、

正常な文字列になります。

ただ、一番初めの

・ソ・ソ・ソ・ソ・ソ・ソ

という謎の文字列が出現しました。

$outには、

$out = '

....

...

';

という感じで入れてあります。

2007/07/18 08:26:06
id:tezcello No.4

回答回数460ベストアンサー獲得回数69

ポイント18pt

問題点の切り分けから...

  • 「文字化け」はPCで見たとき?携帯で見たとき?
  • 「文字化け」は全ての文字?(フォームで入力した文字だけとか)
  • 「文字化け」しているページをPCで見て、どのエンコードにすると正しく表示される?
  • 確認用のページを出力するPHPスクリプトを Shift-JIS で書いた場合はどうなるでしょう?
  • mbstring.http_output がセットされていませんか?(多分大丈夫だと思いますが)

metaタグは単なるお知らせらしいので、これを変えただけでは思うように変わりません。

エンコードの場合、

  • ヘッダ
  • metaタグ
  • 実際のデータ

と指定できるところがあり、ブラウザによってどれを見ているかは様々です。


実際に Xrea で、UTP-8 で書いたものを Shift-JIS に変換して出力してみましたが、手元の携帯ではチャンと見えています。(もっとも、最近の携帯は UTF-8 のページもチャンと見る事ができるようですが)

id:onigirin

どうもありがとうございます。

・文字化けは、携帯とPC両方なります

・文字化けは、全ての文字で発生します

・ブラウザで見ると、euc/utf-8/shift-jis/jis全てダメでした

・Shift-JISで再保存しましたが、ダメでした

・mbstring.http_outputは書いていないです

確かに最近はUTF-8でも見ることができますよね。

初めはそれでいこうとしたのですが、

はてながShift-JISっぽいからあわせようかなぁと思ったら

ハマッてしまいました・・・。

2007/07/18 15:00:07
id:shiroxcom No.5

回答回数140ベストアンサー獲得回数5

ポイント18pt

絵文字で文字化けしているのでしょうか?

SJIS-winという文字コードを使えば解消されるかもしれません

http://hain.jp/index.php/tech-j/2006/10/04/

id:onigirin

どうもありがとうございます。

絵文字は使っていないです。

絵文字が入ると、これまたややこしくなりそうですね。

先にチェックしておきますね。

2007/07/18 15:00:50
id:shiroxcom No.6

回答回数140ベストアンサー獲得回数5

ポイント18pt

SJIS文字コード下で str_replace などの置換系の関数を使用して

日本語の文字列を日本語で置換したりすると、

「・ソ・ソ・ソ・ソ・ソ・ソ」のような文字化けを起こした記憶があります。

そういった処理があった場合は、一度置換する文字と置換される文字、両方を(UTF-8、EUC-JP)などに変換してから、str_replace などを行い、また SJIS に戻してやる必要があります。

見当違いでしょうか?

id:onigirin

どうもありがとうございます。

置換処理も修正してみましたが、

ソは出てきました・・・。

2007/07/19 11:17:54
  • id:Bookmarker
    > ただ、一番初めの<!DOCTYPE...の前の部分に・ソ・ソ・ソ・ソ・ソ・ソという謎の文字列が出現しました。

    それが原因でしょう。
    文字符号化方法を知るまでに ASCII の範囲外のバイト値が現れると、タグを正常に解釈できなくなる可能性があります。

    文字符号化方法の指定:
    http://www.asahi-net.or.jp/~sd5a-ucd/rec-html401j/charset.html#h-5.2.2
  • id:tezcello
    > 文字コードをShift_JISにして読み直すと、
    > 正常な文字列になります。
    という事は、エンコードの変更は上手く機能していますね。


    > ただ、一番初めの
    > ・ソ・ソ・ソ・ソ・ソ・ソ
    > という謎の文字列が出現しました。
    ブラウザのエンコードをいろいろ変えるとチャンと表示できるかも知れませんね。ひょっとすると UTF-8 なのでは?
    スクリプトでその文字を出力している部分を探すのが解決の近道では?
       どこかで(デバッグ用などで)変数の内容を書き出したり、不用意に出力していませんか?
  • id:onigirin
    ■Bookmarkerさん

    どうもありがとうございます。
    この謎の文字列がよくわからないです・・・。

    試しに
    $test = mb_convert_encoding("あいうえお", "SJIS", "UTF-8");
    echo $test;
    とし、その後に
    echo $out;
    しました。

    結果、「あいうえお」も文字化けしていました。
    ソースを閲覧し、テキストを「Shift-JIS」で読み直すとソソソと「あいうえお」を含み、全て正常に表示されています。
    再度「UTF-8」で読みなおすと、文字化けした同じ内容になりました。
    このとき、ソースに「ソソソ」や「あいうえお」は表示されていませんでした。
  • id:onigirin
    ■tezcelloさん

    どうもありがとうございます。

    ブラウザのエンコードをいろいろ変えてみましたが、
    どうもうまく表示されないです。


    少し新しい発見がありました。
    IE系のブラウザで見ていたのですが、
    firefoxで見てみました。

    すると、文字化けせずに表示されていました。
    ただ、テキストの初めに

    ・ソ・ソ・ソ・ソ・ソ・ソあいうおえ

    は表示されています。
    この
    ・ソ・ソ・ソ・ソ・ソ・ソ
    が出力されている場所を探していますが、なかなか見つからないです・・・。
  • id:Knoa
    > ・ソ・ソ・ソ・ソ・ソ・ソ
    > が出力されている場所を探していますが、なかなか見つからないです・・・。

    すでに結構な規模のプログラムになっているのでしょうか?
    プログラムの一部分だけを切り取って、再現するか試してみてはどうでしょう。

    あと、差し支えなければそのページのURLをずばりここに書き込んでもらえると、なにかヒントが掴める可能性もあります。
  • id:onigirin
    ■Knoaさん

    どうもありがとうございます。
    小規模なのですが、出力しているところが無いので
    何故だろう・・・と思っていました。

    先ほど、なんとか解決できました。
    コメント欄にもう一度書きますね。
  • id:onigirin
    ■解決しました!■

    教えて頂いた方法を順に試してもうまくいかず、
    思い切ってイチから書き直しました。

    少しずつコピペする形で再度初めから書き直したのですが、
    少しずつ出力させて確かめていきました。

    その結果、正常に表示されました。


    そこで、前回と違うところは、
    前回は「BOMつき」で保存していて、
    途中でアドバイスを頂いて「BOM無し」にしました。

    今回は、初めから「BOM無し」で書きました。

    そのため、
    前回の「BOM無し」で再保存したときに、
    ファイル数が多いため、し忘れたものがあったのかもしれません。

    確認のため、
    今回正常に表示されているファイルを
    「BOMあり」に一部してみたところ、
    「BOMあり」のファイルを読み込んだ数だけ
    「・ソ」が出てきました。
    前回は「4個」読み込んだため、
    「4個」+「自ファイル」の5つ分「・ソ」が出ていた、
    ということかもしれません。


    なんとも情けないミスで申し訳ないです・・・。
    どうもお騒がせしました。

    いろいろアドバイス頂けたおかげで
    諦めずになんとか解決できました。

    ありがとうございました。
  • id:Bookmarker
    > 前回と違うところは、
    > 前回は「BOMつき」で保存していて、
    > 途中でアドバイスを頂いて「BOM無し」にしました。

    そういえば、UTF-8 の BOM は「EF BB BF」の3バイトなので、
    Shift_JIS として解釈すると「・ソ」となりますね。
    # 「EF BB」には文字が割り当てられていないので、
    # どういう表示になるかは不定ですが。

    > ただ、一番初めの<!DOCTYPE...の前の部分に・ソ・ソ・ソ・ソ・ソ・ソという謎の文字列が出現しました。

    この時に、文字コード表を見れば良かった(^^;

    > 今回は、初めから「BOM無し」で書きました。

    UTF-8 から Shift_JIS に変換したソフト(テキストエディター?PHP?)が、バグっているのかもしれませんね。
  • id:onigirin
    どうもありがとうございます。

    そこまで深くわかるんですね・・・。
    文字コードにちょっと興味がわいてきました。

    エディタは、EmEditor使ってて、
    デフォルトでUTF-8だと「BOMつき」みたいです。
    今まではShift-JISで書いてり、
    UTF-8の修正がメインだったので
    あまり気にしたことが無かったのがつまづいた原因だと思います。

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

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

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

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