Search

  毎日にもっと楽~を! BLOG Tokyo

2007年3月20日

【MySQL×PHP】文字化け

文字化けの問題は終わらない。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 は不要です。



Bookmark and Share


編集長のおすすめの一冊!2010

comments

comment form

(BLOG Tokyo にはじめてコメントされる場合、不適切なコメントを防止するため、掲載前に管理者が内容を確認しています。適切なコメントと判断した場合コメントは直ちに表示されますので、再度コメントを投稿する必要はありません。)

comment form