PHPとMySQLの文字列設定について
自然言語処理のために文字列のアノテーションを行うためのブラウザインターフェースを、 PHP, MySQL, JavaScript で作っていたのですが、コーパスの文字コードが統一されていなくて、それを UTF-8 に変換して使うために苦戦したので記しておきます。
PHP の文字列関数で文字コードを考慮する場合は、通常の文字列関数 substr, strlen などに接頭辞 mb_ を付与したものになります。すると文字コードを指定すると良く、
<?php echo strlen("あいうえお"); ?> <?php echo mb_strlen("あいうえお", "UTF-8"); ?>
UTF-8 の端末の環境では、前者は 15, 後者は 5 になります。
読み込み用のファイルも UTF-8 にすれば問題なさそうですが、ファイル内容を MySQL に保管したものを取り出していて、そこで齟齬が起きていました。
MySQL において table を作成するとき、文字コードを指定できます。例えばある名前と、アノテーション対象となる文字列の開始位置、そして備考を保存するテーブルを作成します。(文字コードの管理がしっかりできていないと、このインデックスがずれてしまって困るのです。)
mysql> create table annotations (name varchar(64), index int, memo text) default character set utf8;
create table をする際に文字コードを設定しますが、それだけでは正常に動作しない場合があり、 MySQL の文字コードの設定次第では、一例として次のようになっている場合があります。
mysql> show create table annotations; | Table | Create Table | | annotations | CREATE TABLE `annotations`( `name` varchar(64) CHARSET SET latin1 DEFAULT NULL, `index` int(11) DEFAULT NULL, `memo` text CHARSET SET latin1 DEFAULT NULL )ENGINE=InnoDB DEFAULT CHARSET=utf8
中味の varchar や text が latin1 になっているのです。 MySQL のデフォルト文字コードの設定は、
mysql> status
Server characterset: utf8
Db characterset: latin1
Client characterset: utf8
Conn. characterset: utf8
となっており、 Db characterset が latin1 になっているからかもしれません。
そもそも status で表示されるこれらの文字コードを修正すれば解決するかもしれませんが、なぜか Db characterset だけは変更する方法が分かりませんでした。ですが、テーブルを作るときにテーブル内部のそれぞれの項目に対して文字コードを設定することができます。
mysql> create table annotations (name varchar(64) charset set utf8, index int, memo text charset set utf8) default character set utf8;
インターフェースはこれで正常動作しました。