phpでmysqlのデータベースを読み込み、表示させるプログラムを稼働させているのですが、sixcoreで文字化けが発生しました。
ãã®ä»–
上記のような文字化けです。
さくらのレンタルサーバーの頃からphpmyadminで同様の文字化けが起きていたのですが、Web上では正常に表示されていました。
sixcoreのphpmyadminも同じ文字化けが起きています。
phpプログラム側からmysqlに対して入出力を行うプログラムがあり、全てを修正するには時間を要すると思われます。
今回緊急的にサーバーの移動を行いたい為、Web上で表示正常に行われれば稼働させたいです。
調べた結果、元の文字列がUTF8で入力decodeがLatin-1で出力encodeがUTF8である場合に起こる文字化けであると分かりました。
が、どこを修正すれば良いのか皆目見当がつきません。
どうかお力をお借りしたく存じます。
試したこと
・mysqlのcharacter_setを揃えた。
・php.iniの共通部分を揃えた。
・mb_convert_encoding($xxxx,"iso-8859-1","utf8");でデータ引き出し時に文字コードを変更。→ ��?度は�� 少しだけ読めるがほぼ文字化け
sixcore
php var: 5.3.3
mysql var: 5.0.95
sakura
php var: 5.3.27
mysql var: 5.5.28
共通
character_set_client utf8
character_set_connection utf8
character_set_database ujis
character_set_filesystem binary
character_set_results utf8
character_set_server ujis
character_set_system utf8
共通
MySQL接続の照合順序:utf8_general_ci
MySQLの文字セット: UTF-8 Unicode
php.ini さくら設定(sixcoreの設定もこれに合わせています)
mbstring.language = "neutral"
mbstring.internal_encoding = "UTF-8"
mbstring.encoding_translation = Off
mbstring.func_overload = "0"
mbstring.http_input = "pass"
mbstring.http_output = "pass"
session.auto_start = "0"
session.use_trans_sid = "0"
session.use_only_cookies = "1"
magic_quotes_gpc = Off
short_open_tag = On
safe_mode = Off
register_globals = Off
allow_url_fopen = On
allow_url_include = On
upload_max_filesize = "2M"
display_errors = On
error_reporting = "E_ALL & ~E_NOTICE & ~E_DEPRECATED"
asp_tags = Off
variables_order = "EGPCS"
date.timezone = "Asia/Tokyo"
output_buffering = On
なんか設定に色々問題ありそうなのですが、先に回答を。
mysqlからデータをINSERTする前にmysqli_set_charsetもしくはmysql_set_charsetをかませて見てください。どれかの文字コードで正常に取れるはずです。
mysqli_set_charset('ujis'); mb_convert_encoding($xxxx,"utf8","auto");
と、これでいけるかと思ったのですが
>調べた結果、元の文字列がUTF8で入力decodeがLatin-1で出力encodeがUTF8である場合に起こる文字化けであると分かりました。
この文が良く分かりません。入力decodeがLatin-1ということはmysqlには生データではなくエンコードした英数字を保存しているのでしょうか?英数字ならば文字化けなど起きるはずないのでなにがなんやら…
mysql内部はEUC-JPになっているのでひとまずEUC-JPを疑ってみてください。
・MySQLの設定がそもそもおかしい
character_setに「ujis」と「utf8」が混在しているのでわけが分からなくなっています。
ujisはutf8とは関係なくEUC-jpのことです。
なので質問者さんが書いた設定だと、標準設定ではmysql内はEUC-JPだけどアクセスしたり読み書きのときはUTF-8という状況になるはずです。(PHP側でSET NAMESなどしていれば話は別ですが)character_set_filesystem以外は統一したほうがいいと思います。
・保存されている内容がそもそも化けている可能性
EUCJPにUTF-8で書き込んだ場合MYSQL上で既に化けている可能性があります。これをUTF-8でまた引っ張ってくるとEUCで文字化けしたデータをさらに化けさせて持ってくることになると思います。ここまでくるとよくわからない文字列になっているのでどうやっても戻せないかも?
EUC-JPでアクセスしてみれば正常に取れるやも知れません。
・PHPのバージョンなどは関係ない
ちなみにPHP内部はUTF8ですよね?
・mb命令も一応書いておく
mb_convert_encodingのせいという可能性もあるので
mb_language('ja'); mb_internal_encoding('UTF-8'); mb_http_output("UTF-8");
このあたりも調整してみてください
・同じ設定なのになぜ化ける?
移行時にmysql自体が化けてしまったのかもしれませんが詳しくは謎です。
とっかかり回答レベルになりましたが、PHPからMYSQLを呼び出す部分など公開いただければもう少しまともに(他の人が)答えられるかもしれません(MYSQLのサーバ名やIDパスワードなどは伏せていただいて出せるところだけ)
ご回答有難うございます。
2014/02/06 19:45:52>調べた結果、元の文字列がUTF8で入力decodeがLatin-1で出力encodeがUTF8である場合に起こる文字化けであると分かりました。
とエラそうに書いてしまいましたが、参考の記事で文字化けの実験をされていて該当したのが上記の状態でしたので一応記載させて頂きました。
参考記事のURL
http://www.drk7.jp/MT/archives/001939.html
因みにさくらとsixcoreのphpmyadmin内は全く同じ文字化けでデータが格納されていることが確認できます。
なので、元データは同じ状態で入っているものではないかと思います。
また、半角英数字は文字化けせずマルチバイト文字のみ文字化けしています。
mb_convertでujisにした結果◆に?という形で文字化けしました。
プログラム自体はさくらとsixcoreで全く同じものを使っています。
sixcoreのmysqlmyadminから直接編集を行い、文字化けした文字列を修正したところWebでもその部分だけ文字化けせずに表示されました。
mysqlから出力した文字列のみ文字化けし、プログラムに直接記載してある文字列は文字化けしていません。
テストしてみましたがわかりませんでした。
2014/02/10 12:36:59mysqlのテーブルはutf8_general_ciです
mb_language('ja');
mb_internal_encoding('utf-8');
//mb_internal_encoding('iso-8859-1');
mb_http_input("pass");
mb_http_output("pass");
error_reporting(6135);
ini_set( 'display_errors', 1 );
$link = mysqli_connect('localhost', 'root', '','db_a');
mysqli_set_charset($link,'utf8');
$result = mysqli_query($link,"SELECT * FROM `table_hoge` WHERE `cell_hoge` LIKE '%'");
$row = mysqli_fetch_assoc($result);
$text = $row["cell_hoge"];
$text = mb_decode_mimeheader($text);//化けないのでテスト用æååãã§å°ã
$text = mb_convert_encoding($text,"iso-8859-1","auto");//iso-8859-1、utfとするとæååãã§å°ã
var_dump($text);
?>
>mb_convert_encoding($xxxx,"iso-8859-1","utf8");でデータ引き出し時に文字コードを変更。→��?度は�� 少しだけ読めるがほぼ文字化け
latin1で使えない文字が入っているため、元に戻らないんだと思います。
文字が通信のどこかでデコードされているので化けているっぽいですが、どこなのかが分かりませんでした。