LoginSignup
4
4

More than 3 years have passed since last update.

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

Last updated at Posted at 2019-11-17

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とコンソールで文字化けしないことを確認。

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4