Posted at

CakePHP3+MariaDBで4バイト文字を保存する方法

More than 1 year has passed since last update.

CakePHP3を使った開発現場での話。

打合せで文字コードの話から、サロゲートペアってどうする!?との話題になった。私自身、文字コード周りにそこまで明るくないので、サロゲートペアの詳細を知りたい方は、以下を参照頂きたい↓↓↓

http://www.magata.net/memo/index.php?%A5%B5%A5%ED%A5%B2%A1%BC%A5%C8%A5%DA%A5%A2

正直こんなマニアックな漢字を使うか?対応必要?と思ったが、人の名前に使われる漢字も一部あり、また最近では漢字以外でも色んな絵文字が生み出されていることから、さすがに無視は出来ないので、utf8mb4使って対応することになった。

その時の作業手順のメモ書きです。


MariaDBの文字コード変更

デフォルトでは以下の設定となっていた↓↓↓

MariaDB [(none)]> show variables like 'char%';

+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.01 sec)

まずはutf8mb4に変更するため、/etc/my.cnfを確認。

[client-server]

#default-character-set=utf8mb4

#
# include all files from the config directory
#
!includedir /etc/my.cnf.d

my.cnfは殆ど空ファイルで、/etc/my.cnf.d配下に設定ファイルがある。

/etc/my.cnf.d/server.cnfに以下2行を追記。

[mysqld]

character-set-server = utf8mb4
skip-character-set-client-handshake

次に/etc/my.cnf.d/client.cnfに以下を追記。

[client]

default-character-set=utf8mb4

一度MariaDBを再起動し、再度文字コードを確認する。

MariaDB [(none)]> show variables like 'char%';

+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | utf8mb4 |
| character_set_server | utf8mb4 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

上のようにutf8mb4に変更されていればOK!!

登録先のテーブルもutf8mb4で定義。

今回はCREATE文の最後にコレを付与して定義した。

DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci

既に作成済みのテーブルはALTERとかで対応。


CakePHP3のapp.php修正

プロジェクト配下/config/app.phpのDatasourcesに設定されている文字コードを変更。

'Datasources' => [

'default' => [
'className' => 'Cake\Database\Connection',
'driver' => 'Cake\Database\Driver\Mysql',
'persistent' => false,
'host' => 'localhost',

//'port' => 'non_standard_port_number',
'username' => 'root',
'password' => '',
'database' => 'Test',
'encoding' => 'utf8mb4',
'timezone' => 'Asia/Tokyo',

デフォルトではencodingがutf8になっていると思われる。

上の対応をやってあげれば、文字化けせずに登録されるはず。

+----+----------------+------------------+

| id | test_code | test_name |
+----+----------------+------------------+
| 1 | W00001 | 𡈽𡈽𡈽𡈽 |
| 2 | W00002 | 𡈽𡈽𡈽𡈽 |
+----+----------------+------------------+

登録値が文字化けせずに確認出来た。


4バイト文字に対応していない?ツールについて

今回Windows環境で動作検証するにあたり、teratermやA5SQLを利用したが、tera termでのUTF-8は3バイトまでしか変換されないらしく、サロゲートペア(surrogate pair)や結合文字(combining character)は文字化けして、?になってしまった。

(参考文献)

https://ttssh2.osdn.jp/manual/ja/usage/unicode.html

Windowsの場合、RLoginというターミナルツールがサロゲートペアも文字化けせず、表示してくれるので、文字化けして困ったらコチラをオススメします(tera term使ってた人なら、あまり違和感なく使えるはず)

http://nanno.dip.jp/softlib/man/rlogin/

またA5SQLも同様に文字化けして「?」と表示されていたが、ターミナル上で確認すると問題なく登録されていた。もしかしたら設定次第で、文字化けせずに見れるかもだけど、今回時間が無かったのでそこまでは調べられなかった。

ご参考までに。