MySQLの文字コードに関する質問です


テーブル名 item_info
フィールド名 item_id item_title

item_titleは全角日本語を入れています。

PHPでMySQLからデータを引っ張ってきて表示させています。
echo "id: ".$ro['item_id']."\n";
echo "title: ".$ro['item_title']."\n";

するとこうなってしまいます。

id: 1
title: ???

item_titleに入れているデータが文字化けするのです。
ソースが???になっているのでブラウザの問題では無いです。

違うサーバーだと正常に表示されます。MySQLの文字コード関係の設定ではないかと推測します。phpMyAdminを見て文字コードと関係のあるところをピックアップしました。

*****文字化けするサーバーのMySQL設定*****
MySQL 5.1
MySQL の文字セット: UTF-8 Unicode (utf8)
MySQL 接続照合順序: ujis_japanese_ci

テーブルitem_infoのitem_titleの接続照合順序はsjis_japanese_ciになっています。

*****正常に表示されるサーバーのMySQL設定*****
MySQL 4.0
MySQL の文字セット:ujis
接続照合順序に関しては表示されていません。

これだけの情報でおわかり頂けるかどうか・・。
もしわかる方がいらっしゃったら教えてください。

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

回答5件)

id:taknt No.1

回答回数13539ベストアンサー獲得回数1198

ポイント20pt

http://pbx.homeunix.org/p_blog/rss/1.0.php?tid=320

こちらの以下の引用部分で 解決できますでしょうか?



# 解決方法

fnc_base.inc.phpの function db_connect() に SET NAMES 文を追加

if ($link && mysql_select_db($dbname)) {
mysql_query("SET NAMES $cfg['mysql_lang']");
return $link;
} else {


実際にはPHPとMySQLで文字コード名が違う(UTF-8とutf8とか)ので、このままでは動きませんが、SET NAMES 文を入れるだけで以下のような動作になります。

【ブラウザ】 → 自動判別 → 【PHP】 → $cfg['mysql_lang'] → 【MySQLクライアント・ライブラリ】→ $cfg['mysql_lang'] → MySQLサーバー

この辺については『現場で使えるMySQL』の「6. 日本語処理」が詳しいです。現状のP_BLOGは「Column デフォルト文字コードlatin1での日本語の扱い」の状態かと思われます。

【重要】とは言え、今問題なく動いている方はLatin1で格納されているわけで、これをやみくもに SET NAMES $cfg['mysql_lang'] してしまうと、既存の方々が文字化けしてしまいます! SET NAMES latin1 すればいいのですがPHP側で問題が出るので、$cfg['mysql_lang']周りの実装方法を再検討する必要があるかも知れません。

id:b-wind No.2

回答回数3344ベストアンサー獲得回数440

ポイント20pt

MyNA Web Site

色々と情報が足りないので、リンク先を見て試してみてください。

id:tokyosmash

情報ありがとうございます。

kurukuru-nekoさん情報から

mysql_client_encodingを試してみたところ

latin1と帰ってきました。

リンク先で同じことが書いてありました。。

MySQLの文字コードがメチャクチャになっているんだと思います。どうもありがとうございます。

2007/03/23 14:45:13
id:Yota No.3

回答回数453ベストアンサー獲得回数28

ポイント20pt

phpMyAdminの結果はあまり当てにしないほうがいいですよ。

クライアントとしてのcharacter setを設定をしている可能性があるので。

テストスクリプトを作って

$sql = "SHOW VARIABLES LIKE 'character%'" ;

の結果セットを見たほうがいいです。

下のようになればクライアントもサーバもEUC-JPで、元のスクリプトがそのまま使えるはずです。

character_set_client ujis

character_set_connection ujis

character_set_database ujis

character_set_filesystem binary

character_set_results ujis

character_set_server ujis

character_set_system utf8

id:tokyosmash

character_set_client utf8

character_set_connection ujis

character_set_database sjis

character_set_filesystem binary

character_set_results utf8

character_set_server utf8

character_set_system utf8


こんな感じになります。

見事にばらばらなんですが。。

2007/03/23 18:00:59
id:Yota No.4

回答回数453ベストアンサー獲得回数28

ポイント20pt

個人的にはコンパイルの段階からeuc-jpを想定してやれば問題ないと思うのですが、いまさらという感じもしますので、以下のことを試してみたらどうでしょう。

他の回答とかぶりますが、my.cnfまたはmy.iniに追加する。

[mysqld]

default-character-set = ujis

skip-character-set-client-handshake

[client]

default-character-set = ujis

[mysqldump]

default-character-set = ujis

mysqlデーモン再起動後、もう一度SHOW VARIABLES LIKE 'character%の結果を見る。

id:kurukuru-neko No.5

回答回数1844ベストアンサー獲得回数155

ポイント20pt

character_set_client

character_set_connection

character_set_results

mysql_query("set character set ujis");

で同時に変更可能。

character_set_databaseはDBをに記録されている

文字コードなのでDBの修正必要。

再度作りなおすかalter databaseでDEFAULT

CHARSETを変更。

テーブルも同様に修正が必要。

DB/テーブル内部コードがSJISならそのまま

で運用可能ですが。 EUCに統一が望ましい

と思います。(文字化けの原因なので)

my.cnfの修正する方法既出なので省略

id:tokyosmash

解決しました。

my.cnfは編集できない環境なので諦めかけたのですが、

http://phpbb.xwd.jp/viewtopic.php?p=1170

こちらの情報を見て

mysql_query("SET NAMES sjis", $l);

($lはDBへの接続情報です)

を記述すると正常に表示されるようになりました。

なぜsjisなのか・・。ujisでもutf-8でもダメでした。

色々と検索しているとMySQL4.1以降で文字化けする例がたくさんあるようですね。

レンタルサーバーの仕様を見ているとMySQL4.0が多いのですが、やはりその辺が影響しているのでしょうか。

とりあえずうまくいきましたが、文字コードって複雑でよくわかりません。

アジア人は損してると思っているのは自分だけでしょうか?

みなさんありがとうございました。

2007/03/26 09:50:06
  • id:tokyosmash
    質問文が長すぎて登録できなかったために、PHPスクリプトを一部省略しました。


    $re = mysql_query("SELECT * FROM item_info WHERE item_id = '".mysql_real_escape_string($_GET['ID'])."' LIMIT 1");
    $ro = mysql_fetch_assoc($re);
    echo "id: ".$ro['item_id']."\n";
    echo "title: ".$ro['item_title']."\n";


    これが全文です。今まで使っていたサーバー(質問文の正常に表示されるサーバーというやつです)では正常に表示されているので、スクリプトの問題ではないと思うんですよね。。
  • id:kurukuru-neko
    文字セット及び、テーブル・DBの定義確認

    各サーバーで操作するユーザーで利用
    するdatabaseにmysqlで接続して

    mysql database名
    以下のコマンドを実行
    show ;
    show variables like "char%";
    show create table 作成したテーブル名;

  • id:kurukuru-neko
    >show ;
    間違い
    status;
  • id:tokyosmash
    正常なサーバーは
    character_set    ujis

    文字化けサーバーは
    character_set_client utf8
    character_set_connection ujis
    character_set_database sjis
    character_set_filesystem binary
    character_set_results utf8
    character_set_server utf8
    character_set_system utf8


    という具合です。
    文字化けするサーバーはcharacter_set_clientがutf8だから表示されないのかな・・と思っているんですが。
  • id:kurukuru-neko
    PHPで問題のあるサーバーで
    mysql_client_encodingの文字がujisでない
    と思われます。

    1. mysql_client_encodingを表示。

    2. SQL実行

    3. 強制的にEUCに変更をSQL 3つ実行
    SET character_set_client=ujis
    SET character_set_connection=ujis
    SET character_set_results=ujis


    4. 再度mysql_client_encodingを表示。

    5. 問題SQL実行

    mysql_client_encoding
    http://jp.php.net/manual/ja/function.mysql-client-encoding.php

    my.cnfに
    [client]
    default-character-set=ujis
    を書く

    ======================================

    PHP 5.0.5以上ならmysqliを使えば
    mysqli_set_charset
    http://jp.php.net/mysqli_set_charset
  • id:kurukuru-neko
    SET ???は
    mysql_query("SET xxx=ujis", $conn);

    mysqli MySQL 改良版拡張サポート
    http://jp2.php.net/manual/ja/ref.mysqli.php
  • id:tokyosmash
    追記です。

    http://dev.mysql.com/doc/refman/4.1/ja/charset-connection.html
    こちらを参考にして出来ました。


    SET CHARACTER SET=ujis

    これで出来なかった理由ですが、リファレンスによるとイコールがいらないようです。

    SET CHARACTER SET ujis

    これで正常に表示されました。

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

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

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

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