文字化けの問題は終わらない。character-setをサーバ、クライアント,DBであわせるということは以前にもメモしたが、それだけじゃない。面倒くさい。文字化けの深刻さは、SQL文が文字化けするので、ちゃんとした結果が返ってこない。一見なんのエラーだか、さっぱりわからない。
今回は少し進展した。
phpのスクリプトに
SET NAMES cp932;
という文でうまくいくと以前メモしたが、どうもうまく行かない場合もある。
そんなときは、ujisで対応したらどうだろうか。
SET NAMES ujis;
また、my.ini(MySQLの設定ファイル(my.cnf))の[mysqld]の部分に下記を追加すると自動変換機能がオフになる。これで、文字化け問題を回避できる場合もある。
my.ini
[mysqld]
skip-character-set-client-handshake
さらにMyNAパッチを当てたlibmysqlclientおよびlibmysql.dllを入れ替える。
パッチのダウンロード
C:\php5\とかC:\WINDOWS\SYSTEM32\にコピーすればよい。
phpスクリプト側でmy.iniを読み込むようなコーディングも必要らしい。
PHP version 4 の場合
読めない。[client] に書いても無駄。
http://www.mysql.gr.jp/frame/modules/bwiki/?Contrib のパッチを当てる。
PHP version 5の場合
mysqli モジュールに、my.cnf を読む関数が用意されている。
mysqli_options(connection, MYSQLI_READ_DEFAULT_FILE, "/etc/my.cnf");
mysqli_options(connection, MYSQLI_READ_DEFAULT_GROUP, "php");
mysql コマンドでは大丈夫なのに、PHP,perl,accessなどで文字が ? に化けるのは?(文字化け) †
良くある勘違いは、
「mysqlコマンドが動いているから、自分のアプリも正しくコード変換するだろう」
というものです。
これは間違いです。
次の節の概念図をじっくり見てください。
MySQL サーバーとおしゃべりしている libmysqlclient.so (libmysql.dll) に、キャラクターセットが埋め込まれています。
mysql コマンドには default-character-set のオプションがあり、キャラクターセットの指定ができます。
これは libmysqlclient.so (libmysql.dll) の埋込キャラクターセットを上書きします。
しかし、MySQL AB が提供しているコマンド(mysqldump, mysql, mysqlimport等)や MyODBC 以外の、
別の誰かが作ったアプリやコマンドは、
my.cnf を読んだり、default-character-set オプションがあったりするわけではありません。
my.cnf を読んだり、default-character-set オプションが使えたり、SET NAMES 文が実行されたりするのは、
あくまでも、アプリ側の責任、作り手の責任なのです。
上の図で言えば、PHPMyAdmin や PHP 自身の部分に、キャラクターセットの指定をする処理や my.cnf を読む処理を、作り手が意図して書かない限り、実現しないのです。
これは perl だろうが Ruby だろうが、access だろうが、PHP と同じです。
(MyODBC(Connector/ODBC)は設定をすることで、my.cnf の [odbc] グループを読みます。
access で MyODBC を使用しているなら、my.cnf を読むオプションを有効にしておきます。)
コードを書くのが嫌なら(変更することが出来ない状況なら)、libmysqlclient (libmysql,dll) の埋込キャラクターセットを変えるのです。
これは libmysqlclient(libmysql.dll)のコンパイルのし直しを意味します。
なお、5.0.13-rc 以上では、mysqld --skip-character-set-client-handshake とすることで、libmysqlclient はサーバーのキャラクターセットに合せるようになります。
1 つのサーバーで 1 つのキャラクターセットしか使用しない(4.0までのように)のであれば、skip-character-set-client-handshake オプションの指定だけで OK です。
このとき、libmysqlclient の re-compile は不要です。