Help us understand the problem. What is going on with this article?

怪現象?PHP7にしたらDB文字化け

PHP5から7へバージョンアップした時に発生した怪現象(?)です。

解決策(詳細は後述)

  • mysqldumpにて文字コード:latin1でエクスポート
  • エクスポートしたファイル内の"SET NAMES"の文字コードをutf8へ変更してインポート

前提

  • Linux(CentOS7) + Apache + MariaDB + PHP
  • 2015年にMinimalからインストールして構築しました

事象

  • PHPのバージョンアップ後にDB文字化けが大発生しました、パニクりました
  • Webアプリで表示されるDBデータが全て文字化け(なぜか文字化けしないテーブルもありました)
  • MariaDB5から10へバージョンアップしてみましたが、ダメでした
  • PHP5に戻すと、Webの文字化けはなおりました…
  • 2017年に構築した同要件のWebサーバーは、同手順でPHPをバージョンアップしても、当事象は発生しませんでした

調査

そもそも、コンソール上でも文字化けしている

元々、コンソール上は文字化けしていた気も…ほとんどコンソール上でSQLのオペしないので…という言い訳

SELECT test_col FROM test_tbl LIMIT 1; 
+-------------------------------------------------------+
| test_col                                              |
+-------------------------------------------------------+
| a?a?1a??cӬa?1a?a??a?                              |
+-------------------------------------------------------+

バイナリで表示したところ、やけに長い

文字コードはutf8、test_colの中は"テスト用スレッド"と入っているため24バイトのはずです。

SELECT test_col, HEX(test_col) FROM test_tbl LIMIT 1; 
+-------------------------------------------------------+------------------------------------------------------------------------------------------------------------+
| test_col                                                   | hex(test_col)                                                                                               |
+-------------------------------------------------------+------------------------------------------------------------------------------------------------------------+
| a?a?1a??cӬa?1a?a??a?                              | C3A3C692E280A0C3A3E2809AC2B9C3A3C692CB86C3A7E2809DC2A8C3A3E2809AC2B9C3A3C692C2ACC3A3C692C692C3A3C692E280B0 
+-------------------------------------------------------+------------------------------------------------------------------------------------------------------------+

文字コード関連の環境変数を確認したところ、serverの文字コードがlatin1

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     | latin1                     |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+

clientの文字コードをlatin1にして再度表示したところ、文字化けが解消

SET NAMES latin1;
SELECT test_col, HEX(test_col) FROM test_tbl LIMIT 1; 
+--------------------------+------------------------------------------------------------------------------------------------------------+
| test_col                 | hex(test_col)                                                                                               |
+--------------------------+------------------------------------------------------------------------------------------------------------+
| テスト用スレッド         | C3A3C692E280A0C3A3E2809AC2B9C3A3C692CB86C3A7E2809DC2A8C3A3E2809AC2B9C3A3C692C2ACC3A3C692C692C3A3C692E280B0 |
+--------------------------+------------------------------------------------------------------------------------------------------------+

mysql latin1 utf8 文字化けなどで検索していると発見

https://www.gcd.org/blog/2009/09/177/
各文字をlatin1と判断されて、utf8でエンコードした文字列がDBに登録されていました。

解決策

mysqldumpにて文字コード:latin1でエクスポート

mysqldump -u root -p --default-character-set=latin1 test_db > test.sql

エクスポートしたファイル内の"SET NAMES"の文字コードをutf8へ変更してインポート

参考
https://qiita.com/tukiyo3/items/77c75f355e71d52e65f7

/etc/my.cnf.d/server.cnfの"[mysqld]"の下に以下を追加

/etc/my.cnf.d/server.cnf
character-set-server = utf8

mariaDB再起動

Webとコンソールで文字化けしないことを確認。

k_iwamoto
東京 東新宿 / ICT開発 構築 代表取締役 社長
https://www.chuo-system.co.jp/ceo/
chuo-system
中央システムは「人生とICTを楽しみ、さらに豊かになるループ」を永続します。2020年に創業40周年を迎えた、老舗ICT企業です。☆東京 東新宿 / ICT開発 構築☆ICT研究開発 / Buzzworks
https://www.chuo-system.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away