UTF8とEUC-JPを1つのサーバで混在させるときは

2009年5 月8日  |  Written by matsumoto  |  under PHP, Perl, サーバー Yahoo!ブックマークに登録    はてなブックマーク - UTF8とEUC-JPを1つのサーバで混在させるときは

細かいプロジェクトが積み重なってくると、プロジェクトによって色々な文字コードが混在する状況になりがちです。
ありがちなパターンなのですが、ちょっと昔のプロジェクトだとEUC-JP、最近のプロジェクトはUTF-8で構成している場合などです。

別々のサーバで開発ができれば、それぞれのサーバの文字コードをキメ打ちすればいいのですが
開発サーバが1台で、それぞれのプロジェクトを共有する場合、1台で文字コードを使い分けないといけなくなります。

意識するのが以下の3点です。

  • シェル
  • MySQLなどのDBサーバ
  • Webアプリケーション

特に「デフォルトがUTF8で、イレギュラー扱いでEUC-JP」というパターンが多いのですが
弊社ではこれらについて以下のように対応しています。

シェル

シェル本体

個人的にですがデフォルトでzshを使っています。イレギュラー扱いでbashを起動させるようにしています。

デフォルトシェルをshに設定して、以下のように分けます。

  • UTF-8の場合

     → putty(UTF-8)  → shでログイン → zshを起動
    • .zshrc に以下を設定しています

      .zshrc
      export locale=ja_JP.UTF-8
  • EUC-JPの場合

    →putty(EUC-JP) → shでログイン → bashを起動
    • .bashrc に以下を設定しています

      .bashrc
      export locale=ja_JP.eucJP

※利用するシェルを指定しているわけではありませんので、csh tcshなどのシェルを利用しているエンジニアもいます。

.vimrc

vimは通常 ~/.vimrc を読み込みますがオプションで別のconfigファイルを読み込むことができます。
これを利用して bash(EUC-JP)側では違う.vimrcを読み込ませ、文字コードを強制的に認識させます。

※本来は自動認識が一番スマートなのですが、うまいこといかず・・・

  • zsh + UTF-8の場合

    .vimrc
    
    set encoding=utf-8
    set fileencoding=utf-8
    set ambiwidth=double
  • bash + EUC-JPの場合

    .vimrc-euc-jp
    
    set encoding=euc-jp
    set fileencoding=euc-jp

これらを設定して .bashrc でエイリアスを設定しています

alias  vim="vim -u ~/.vimrc-eucjp"

.screenrc

screenコマンドも文字コードを明示的に分けています

  • zsh + UTF-8の場合

    .screenrc
    
    defencoding utf-8
    encoding utf-8 utf-8

.zshrc でエイリアスを設定しています

alias screen="screen -U -c ~/.screen"
  • bash + EUC-JPの場合

    .screenrc-euc-jp
    
    defencoding eucJP

.bashrc でエイリアスを設定しています

alias screen="screen -c ~/.screenrc-eucjp"

MySQL

MySQLはサーバとクライアントで文字コードがごちゃごちゃになりがちですが、
以下のようにルール付けしています。

my.cnf

my.cnfでは明示的にutf8を指定します。
ただしskip-character-set-client-handshakeは使用していません。ujis(EUC-JP)時に強制的にUTF-8になってしまうからです。

/etc/my.cnf

[client]
 default-character-set = utf8
[mysqld]
default-character-set = utf8
character-set-server = utf8

データベースの作成(CREATE DATABASE)

データベースの作成(CREATE DATABASE)時に、そのDBでデフォルトとなる文字コードを指定します。
これにより、 load data infile xxx などの外部CSVのインポートでも 文字コードが正しく認識されます。

UTF-8

mysql> create database database_name default character set utf8;

EUC-JP

mysql> create database database_name default character set ujis;

テーブルの作成 (CREATE TABLE)

テーブルの作成 (CREATE TABLE)時も明示的に利用する文字コードを指定します。

UTF-8

CREATE TABLE ex_table (
  ....
) default charset=utf8;

EUC-JP

CREATE TABLE ex_table (
  ....
) default charset=ujis;

mysqlクライアント

接続時にEUCの場合に default-character-set オプションをつけます。

毎回は面倒なので .bashrcに以下のエイリアスを設定しています。

UTF-8

alias mysql-connect="mysql -uuser -p --default-character-set=utf8"

EUC-JP

alias mysql-connect="mysql -uuser -p --default-character-set=ujis"

ウェブアプリケーション

PHP

PHPでのコーディングではシェルとターミナルの組み合わせをしっかり指定しておけば
文字化け自体の問題は特には無いと思います。

EUCの場合のみ、DBへの接続はプログラム側で最初の接続時に

set names ujis;

とSQLを発行させています。

Perl

UTF8フラグと戦わないといけません・・・
弊社ではUTF8フラグをonにした状態をデフォルトと想定しています。

#!/usr/local/bin/perl

use utf8;
use strict;
use warnings;
.
.
.

などです。

DBI経由でMySQLに接続するときはデフォルトで/etc/my.cnfを読み込みます。

EUC-JPで読み込みたい場合は、文字コードセットがデフォルトですとUTF8に設定していますので、別途アプリ用のcnfを作成しています。

  • /home/proj/config/dbi.my.cnf

    [client]
    default-character-set=ujis

接続クライアントの文字コードを指定しただけです。
このファイルをDBIの接続の都度読み込ませます。

  • DBIで接続

    $dbh = DBI->connect('dbi:mysql:dbname;host=localhost;mysql_read_default_file=/home/proj/config/dbi.my.cnf', $user, $password);

dsnに mysql_read_default_file というファイルを読み込むオプションを追加しています。

大体このような形で運用しています。
非効率な部分もあるかと思いますが、ご意見を頂けますと幸いです。

参考リンク

perl EncodeモジュールとUTF8の扱いについて

現在コメントはありません | コメントの投稿はこちら

コメントを書き込む

コメント本文

※コメントのフォーム内で以下のタグがご利用いただけます
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

私はチーム・マイナス6%です