#問題
先日、Laravelで制作しているクチコミ投稿サイトをHerokuにデプロイしました。データベースにはClearDB MySQLを使用していますが、日本語の文字化けが発生しました。**YouTube万屋エンジニアチャンネル様**の多大な協力のおかげで解決できました。
###状況整理
- MacターミナルのMySQLでINSERTしたデータはブラウザで表示すると
ƒ–ルーノート最高ã®ãƒŸï
みたいに文字化けする - 一方ブラウザ上のフォームから投稿した内容はターミナルで表示すると
?????????
となる - ただし、ターミナルでINSERTしたデータはターミナル上ではきちんと表示され、ブラウザのフォームから投稿したデータはブラウザ上ではきちんと表示される
ちなみに、teratailにも質問投稿していました→ https://teratail.com/questions/291553?reply=true
###環境確認
Heroku, ClearDB MySQL, Laravel 7.26.1, MacOS
#原因は何か?
上のteratailを見ていただくとわかりますが、私は文字コードに関連しそうな箇所の見当をつけるべくviewの
原因はMySQLクライアントの文字コード設定でした。ターミナルでMySQLにログインして下記コマンドで確認できます↓
mysql> show variables like 'character%';
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | latin1 |
| character_set_connection | latin1 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | latin1 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
↑このlatin1をutf8に変更する必要があります。変更にはMySQLの設定ファイルをいじることが必要です。
#MySQLの設定ファイルを探せ!
設定ファイルはmy.cnfで、複数のディレクトリに存在していて、優先順位があるみたいです。下記コマンドで、それぞれのディレクトリと優先順位を確認できます。
$ mysql --help | grep my.cnf
order of preference, my.cnf, $MYSQL_TCP_PORT,
/etc/my.cnf /etc/mysql/my.cnf /usr/local/etc/my.cnf ~/.my.cnf
1つめのディレクトリにはファイルが存在しませんでした...↓
$ cd /etc/my.cnf
-bash: cd: /etc/my.cnf: No such file or directory
2つめはディレクトリが存在しませんでした...↓
$ cd /etc/mysql
-bash: cd: /etc/mysql: No such file or directory
3つめのディレクトリにはありました...↓
$ cd /usr/local/etc
$ ls
bash_completion.d freetds.conf locales.conf odbc.ini openldap php
fonts gitconfig my.cnf odbcinst.ini openssl@1.1 pool.conf
catコマンドでファイルを閲覧します↓catは、concatenate(連結するの意)の略でファイルを閲覧したり連結コマンド。
$ cat my.cnf
# Default Homebrew MySQL server config
[mysqld]
# Only allow connections from localhost
bind-address = 127.0.0.1
mysqlx-bind-address = 127.0.0.1
↑character(文字)に関する設定がありません。これを使っていきます!
その前に一応4つめも↓...ありません。
$ cd ~/.my.cnf
-bash: cd: /Users/私のユーザー名/.my.cnf: No such file or directory
番外編で下記の方法でも探しました。大量の結果が出てきて、しかも長かったので途中でCtrl+cでキャンセルしましたが、2点ほど気になる結果が。
$ find / -name "my*.cnf"
find: /usr/sbin/authserver: Permission denied
/usr/local/etc/my.cnf
/usr/local/Cellar/mysql/8.0.21_1/.bottle/etc/my.cnf
一応中を覗いてみるとこんな感じ↓でもこれは一旦無視。
$ cd /usr/local/Cellar/mysql/8.0.21_1/.bottle/etc
$ ls
my.cnf
$ cat my.cnf
# Default Homebrew MySQL server config
[mysqld]
# Only allow connections from localhost
bind-address = 127.0.0.1
mysqlx-bind-address = 127.0.0.1
#my.cnfファイルに文字コードの設定を追記する
/usr/local/etc/my.cnfファイルをいじっていきます。
下記のように[mysqld]にcharacter-set-server = utf8
、[client]にdefault-character-set = utf8
を追記しました。(アンダーバーとハイフンなどスペルミスお気をつけください!汗)
念のため、開くコマンドは$vi my.cnf
、開いたらINSERTのi
で編集モード、終わったらescボタン
:wq
Enterボタン
です。
[mysqld]
# Only allow connections from localhost
bind-address = 127.0.0.1
mysqlx-bind-address = 127.0.0.1
character-set-server = utf8
[client]
default-character-set = utf8
[mysql]
#結果確認
MySQLを再起動($ mysql.server stop
$ mysql.server start
)して、見てみると...↓
mysql> show variables like "character%";
+--------------------------+----------------------------+
| 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/ |
+--------------------------+----------------------------+
↑character_set_serverがlatin1のままなのは気になりますが、この状態でターミナルからINSERT文で挿入したレコードの日本語はきちんとブラウザで表示され、ブラウザのフォームから投稿して挿入されたレコードはターミナルのMySQLできちんと日本語で表示されるようになりました。
ちなみに、過去に文字化けしたレコードはそのまま文字化けしたままです。
もしこれでうまく行かなかったらぜひコメントください m(_ _)m
YouTube万屋エンジニアチャンネル様、重ね重ねありがとうございました。