質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.46%

  • PHP

    24641questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • MySQL

    7166questions

    MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

  • 文字コード

    242questions

    文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

mysqlで既に文字化けしているものをphpで正常に表示させたい

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 4
  • VIEW 4,651

memo

score 11

表題の件ですが、
DBを直すのが早いと思われるのですが、PHPでの表示のさせ方をご教授頂けますと幸いです。
サーバはロリポップのレンタルサーバとなります。
mysqlはUTF-8でPHPもUTF-8です。
オープンソースの顧客管理システムと、
自分で開発したツールを連携させたいのですが、
顧客管理システムでのデータが下記のように文字化けしております。
ななし
こちらを日本語表示させたいのと文字コード等も教えて頂けますと幸いです。
また、一行だけですのでmb_convert_encoding()のような関数のような簡単に変換できる方法をご教授頂けますと幸いです。
よろしくお願い致します。

その後。。。。
どうやら
mysql_set_charset("utf8");

mysql_set_charset("utf-8");
に(ハイフン入れる)すると正常に表示されるようですが、

そのまま
mysql_set_charset("utf-8");
の設定でDBにUPDATE文を投げるとあのような文字化けをしてしまうようです。

utf-8に合わせるとDB側が文字化けをしてしまうのでどうしたもんか。。。

マークダウンもろくに使えずに申し訳御座いません。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

checkベストアンサー

+3

select hex(..) した場合の文字化けのパターンから http://www.gcd.org/blog/2009/09/177/ で紹介されている誤ってUTF-8の文字列をclientのcharacter setの設定をlatin1にして書き込んで変に変換されてしまった状態であると考えられます。

CREATE TABLE `t1` (
  `id` int(11) NOT NULL DEFAULT '0',
  `message` text CHARACTER SET utf8,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
<?php

$user = 'user';
$pass = 'pass';

$pdo = new PDO('mysql:host=localhost;dbname=test', $user, $pass);

$pdo->exec('set names latin1;'); // わざと間違えた状態にします。

$sth = $pdo->prepare('insert into t1(id, message) values (:id, :message);');
$param = [
    ':id' => 1,
    ':message' => 'ななし',
];
$sth->execute($param);

上記のようなテーブルを用意してテスト用のプログラムを実行すると確かに同じ文字列が挿入されます。

mysql> select * from t1;
+----+---------------------+
| id | message             |
+----+---------------------+
|  1 | ななし           |
+----+---------------------+
1 row in set (0.00 sec)

mysql> select id,hex(message) from t1;
+----+----------------------------------------+
| id | hex(message)                           |
+----+----------------------------------------+
|  1 | C3A3C281C2AAC3A3C281C2AAC3A3C281E28094 |
+----+----------------------------------------+
1 row in set (0.00 sec)

従って、同じようにclient側の状態を間違ってlatin1にしてやれば、この逆の変換が行われて元と同じデータが読み出されます。

<?php

$user = 'user';
$pass = 'pass';

$pdo = new PDO('mysql:host=localhost;dbname=test', $user, $pass);

$pdo->exec('set names latin1;');

$sth = $pdo->prepare('select id, message from t1 where id = :id;');
$param = [
    ':id' => 1,
];
$sth->execute($param);
$row = $sth->fetch();
printf("%d, %s\n", $row['id'], $row['message']);
$ php test2.php
1, ななし

同じやり方で無理矢理読み出すことは出来ると思います。

ただあきらかに間違った形でデータが格納されている状態ですので、顧客管理ソフトウェアの方の誤った文字コードの設定になっている問題を解決してからDBの中身も修正してきれいな状態にするのが本来は望ましいと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/12/28 15:30

    ご連絡ありがとう御座います。
    UTF-8ではなくlatin1にしたところ見事表示されました!
    再現コードまで頂きましてありがとう御座います。

    仰るとおりDBの中身を直さなくてはいけませんよね。
    表題通りのお答えなのでベストアンサーとさせて頂きます。

    またその他のお答え頂けた皆様もこちらからで大変恐縮ではありますが、
    ありがとう御座いました。

    キャンセル

+1

DBを直すのが早いと思われるのですが、

その通り、元のデータを直すのが定石です。元データが外字や機種依存文字 だったりしませんか?
元データの本来の内容は?文字化けした内容を表示されても、元データの本来の内容がわからないのに掲示版で質問されても対応は難しいかと。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/12/18 10:07

    おはようございます
    外字や機種依存文字は使っておらず
    ãªãªã—
    の 元のデータは
    ななし
    となります

    携帯から返信のため見辛くて申し訳ありません。

    キャンセル

  • 2015/12/18 10:50

    文字化けは1件だけということですから、プログラム側で ãªãªã— だったら ななし に変換されては?
    同じような文字化けが起きないよう、だれがどこからどうやって入れたデータなのか文字化けの原因は調べて対応されたほうが良いでしょう。

    キャンセル

  • 2015/12/18 12:47 編集

    説明不足で申し訳有りません。
    一件ではなく日本語で入力されたもの全てが文字化けしている状態となります。
    こちら判定する記述など御座いますでしょうか?

    キャンセル

  • 2015/12/18 13:09

    ごめんなさい
    >>一行だけですので
    とは取り出すのは一行だけという意味でした。。。

    キャンセル

+1

他の方もおっしゃっている通り、DBを直すのが間違いないです。

が、もし単なる文字コードの問題で表示さえできれば取り急ぎOKであれば以下の関数をお試しください。
文字コードを判別して返します。

function hoge($str){
    foreach(array('UTF-8','SJIS','EUC-JP','ASCII','JIS') as $charcode){
        if(mb_convert_encoding($str, $charcode, $charcode) == $str){
            return $charcode;
        }
    }

    return null;
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/12/18 10:08 編集

    おはようございます。
    只今電車のため後で試させていただきます。
    有り難うございます。

    キャンセル

  • 2015/12/18 10:48

    頂いている関数を試してみました。
    やはりUTF-8と表示されます。
    説明が下手で申し訳ないのですが、
    顧客管理ツールでデータの更新と表示は文字化け無しですが、
    そもそもの元データがmysql上で文字化けしております。
    その為顧客管理ツール上で文字コードを書き換えて戻したりと悪さをしているということが判るのですが、現状運用中のツールなのでDBを弄りたくないのが事実です。

    仰るとおり取り合えず正常な表示が出来ればOKとなります。
    お手数をお掛け致しますが何卒よろしくお願い致します。

    キャンセル

  • 2015/12/18 11:11

    ソースとコンフィグを見てみないとなんともいえませんが、ここら辺が参考にならないですか?
    http://wordpress.honobono-life.info/svrmng/mysql%E3%81%AE%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%80%81%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E3%80%81%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%E3%80%81%E3%82%AB%E3%83%A9%E3%83%A0/

    可能であれば簡単な検証環境を作ってDBを弄ってみるのが近道かと思います。

    単に文字コードの問題だけであれば、該当のカラムに入っているデータの正しい文字コードがわかれば変換してクライアントに返す処理で良さそうなのですが・・・。
    認識が違っておりましたら申し訳ございません。

    キャンセル

  • 2015/12/18 13:03

    顧客管理システムはこちらのものをお借りしております
    http://customer.limitlink.jp/
    また文字化け対策としてあるページが有るのですが、
    http://l-groupware.com/support/charset.html
    設定としては同じでした。

    ブログ記事ありがとう御座います。
    レンサバの為、my.cnfが弄れないようでして、、

    SHOW CHARACTER SET;
    では
    Charset|Description|Default|collation
    utf8|UTF-8|Unicode|utf8_general_ci
    となっております。

    >>該当のカラムに入っているデータの正しい文字コード
    仰るとおりこちらが判れば私の方でも対処可能だと思っているのですが、
    初めに頂いた関数の通りUTF-8と表示されているものなので、
    ななし
    自体が何の文字コードが判ればと思っております。
    何卒よろしくお願い致します。

    キャンセル

  • 2015/12/25 10:17

    SHOW CHARACTER SET; はどういう文字集合をサポートしているかの一覧が出るだけで、サーバ・クライアント間の通信などでどう変換するかを調べるには

    SHOW VARIABLES LIKE 'CHAR%';

    等としてcharacter_set_client,character_set_connection,character_set_resultsがどう設定されているかを確認する必要があります。

    また、DBに格納されている文字コードがどうなっているかは化けた後の結果から推測するのは難しいので

    SELECT HEX(文字化けするカラム) FROM 〜

    で入っているデータを16進数表示させそこから調べていくのが良いです。

    こちらが参考になると思います

    http://www.gcd.org/blog/2009/09/177/

    キャンセル

  • 2015/12/25 14:06

    crhg様
    ご連絡ありがとう御座います。
    SHOW VARIABLES LIKE 'CHAR%';
    を実行しますと
    |Variable_name | Value |
    |character_set_client | utf8 |
    |character_set_connection | utf8 |
    |character_set_database | utf8 |
    |character_set_filesystem | binary |
    |character_set_results | utf8 |
    |character_set_server | utf8 |
    |character_set_system | utf8 |
    |character_sets_dir | /usr/share/mysql/charsets/ |
    と表示されます。

    >>SELECT HEX(文字化けするカラム) FROM 〜
    については「ななし」のデータは「C3A3C281C2AAC3A3C281C2AAC3A3C281E28094」と出ましたのです。
    こちらの件については少々調べてみます。


    また進捗としてはphpでutf8_decode()関数を使いますと、
    例えば「ななし」というデータが「なな縺?」とまで出るようになったのですが、
    まだ文字化けしてしまっている状況となりまして、
    htmlソースで<meta charset="utf-8">と設定しているのですが、
    ソースを確認するとshift-jisで表示されてしまいます。、
    データ自体にUTF-8とShift-jisが混在しているような気がしております。
    一度バイナリデータ等何かに変換したものを再度正常に変換して表示出来るようにとも考えておりましたが、
    頭が回りません。

    こちらのサイト様では正常に表示されたものが出るのでまだやり方があると思っております。
    http://ltside.com/enc/

    ご回答ありがとう御座います。

    キャンセル

+1

mysqlに入って以下を直接実行してもだめでしょうか?

mysql>alter table messages default charset=utf8;

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/12/28 13:45

    ご連絡ありがとう御座います。
    上記実行すると

    #1146 - Table 'LAA0******-*****.messages' doesn't exist

    と出てしまいます。
    ロリポップの共有サーバのために許可されていないものかと思われます。

    キャンセル

  • 2015/12/28 13:49

    あ、messagesはテーブル名ですね、
    テスト環境にてやってみます。

    キャンセル

  • 2015/12/28 13:53

    `mysql>alter table テーブル名 default charset=utf8;`
    を直接実行後にwebアプリより日本語入力しましたがやはり文字化けの状態となりました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.46%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • PHP

    24641questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • MySQL

    7166questions

    MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

  • 文字コード

    242questions

    文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。