PHPとMySQLの個人的まとめ
MySQLではまったこと
MySQLの文字化け
今さら何いってんのコイツとかそこ言わない。
文字コードを確認するSQL文「SHOW VARIABLES LIKE ‘char%’;」
MySQL4.1以降はサーバとは別にクライアントの文字コードが設定されている。
クライアント、サーバ間で違う文字コードがセットされていると、一度ucs2変換を通る。
よって、クライアント、サーバ間で違う文字コードを指定することとなり文字化けが起こる可能性がある。
PHPはmy.cnfで[mysql]、[client]を設定しようがクライアントの文字コードはビルド時に指定されたキャラクタセット(通常latin1)。
my.cnfの設定
[mysql] default-character-set = utf8 [mysqld] default-character-set = utf8
mysqlクライアントからチェックすると問題なさげだが…
mysql> SHOW VARIABLES LIKE 'char%'; | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | utf8 | | character_set_results | utf8 | | character_set_server | utf8 |
PHPで接続すると実際は…
| character_set_client | latin1 | | character_set_connection | latin1 | | character_set_database | utf8 | | character_set_results | latin1 | | character_set_server | utf8 |
latin1は1byte文字しか利用できない為に文字化けが起こる。
「character_set_server」をデフォルトのlatin1で利用していた場合は、クライアント、サーバ間で変換が行われないためPHPで利用する分には文字化けは起こらない。
だがDBには破壊された文字が保存されるので、これはすべきではない。
PHPのクライアント文字コードセットを変更するにはビルドし直すか、「SET NAMES 文字コードセット」をクエリする。
「SET NAMES 文字コードセット」は「character_set_client」「character_set_connection」「character_set_results」の文字コードをセットする。
mysql> SHOW VARIABLES LIKE 'char%'; | character_set_client | latin1 | | character_set_connection | latin1 | | character_set_database | utf8 | | character_set_results | latin1 | | character_set_server | utf8 | mysql> SET NAMES ujis; mysql> SHOW VARIABLES LIKE 'char%'; | character_set_client | ujis | | character_set_connection | ujis | | character_set_database | utf8 | | character_set_results | ujis | | character_set_server | utf8 |
MySQLの4.1.15以降、5.0.13以降で「skip-character-set-client-handshake」というオプションが追加された。
クライアントからリクエストがあった場合、クライアントの文字コードをサーバの文字コードと同じものをセットする。
[mysql] default-character-set = binary [mysqld] default-character-set = utf8 skip-character-set-client-handshake
mysql> SHOW VARIABLES LIKE 'char%'; | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | utf8 | | character_set_results | utf8 | | character_set_server | utf8 |
ただし、「skip-character-set-client-handshake」は「character_set_server」の値を参照するので注意。
mysql> CREATE DATABASE sample CHARACTER SET ujis; mysql> USE sample; mysql> SHOW VARIABLES LIKE 'char%'; | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | ujis | | character_set_results | utf8 | | character_set_server | utf8 |
mysqldumpについて。
mysqldumpはデフォルトでutf8の文字コードがセットされている。
[mysql] default-character-set = sjis [mysqld] default-character-set = utf8 [mysqldump] default-character-set = binary
文字セットに「binary」をセットすると「character_set_database」を無変換で出力してくれる。
C:\>mysql -u root sample; mysql> SHOW VARIABLES LIKE 'char%'; | character_set_client | sjis | | character_set_connection | sjis | | character_set_database | ujis | | character_set_results | sjis | | character_set_server | utf8 | mysql> \q C:\>mysqldump -u root sample > dump.sql
上記の場合は出力ファイルの文字コードはEUC-JP。
[mysql] default-character-set = sjis [mysqld] default-character-set = utf8 skip-character-set-client-handshake [mysqldump] default-character-set = binary
「skip-character-set-client-handshake」をセットすると…
C:\>mysql -u root sample; mysql> SHOW VARIABLES LIKE 'char%'; | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | ujis | | character_set_results | utf8 | | character_set_server | utf8 | mysql> \q C:\>mysqldump -u root sample > dump.sql
mysqldumpもクライアントなので変換され、dump.sqlはUTF-8の文字コードとなる。
始めまして。
MySql の文字化けにハマってこちらのページに流れ着きました。
skip-character-set-client-handshake
の一行に救われました。
ありがとうございました。。
初めまして、コメントありがとうございます。
私もかなり悩んでいた所だったので、お役に立って何よりです。
同じ現象が起きた際にphp.iniに以下を追加したら直りました。
mysql.default_charset = UTF-8
追記したらapache reboot
知らないオプションだったので調べてみましたが、標準のオプションではありませんでした。
パッチ(見つかりませんでしたが)を当ててコンパイルすれば、そちらのオプションを追加でいけるようになるかもしれませんが、php.net等からバイナリを取得する場合はオプションがなく、php側では制御できませんので、MySQL側の設定が必要になるかと思います。
通りすがりです。
すごい助かりました、、わかりやすく書いてあって。
ありがとうございます!!
書かれてから1年以上たった今日、この問題をこのページで解決出来た私。
本当にありがとうござます。
始めまして。
> MySQL4.1以降はサーバとは別にクライアントの文字コードが設定されている。
この一言で、問題がなんなのか分からない状態から抜け出すことができました。
本当にありがとう!
はじめまして。
ずーっと悩んでましたが、おかげで解決しました。
本当にありがとうございました。
skip-character-set-client-handshake が魔法に感じました。
どうも、初めまして。
他の方も書かれていますが、まさにskip-character-set-client-handshakeに救われました。
著名なブログ(と書いては失礼かも知れませんが)では一切書かれていないので、もうお手上げ状態でした。
本当に、本当に助かりました。
はじめまして。助かりました?
半月ほど悩んでいたのですが「skip-character-set-client-handshake」のお陰で解決できました。
本当にありがとうございます。
助かりました。
みなさんと同じく、
skip-character-set-client-handshake
に救われました。ありがとうございました。
はじめまして
ここのページのおかげで、非常に助かりました!!
昨日、この問題にぶつかり、解決策が見つからないまま
行き詰っていました。
このブログを見つけたおかげで、終電で帰ることができました。
今後もこちらのブログを参考にさせて頂くつもりです。
ありがとうございました!
はじめまして。
今さらですが、文字化けをこのページのおかげで直すことができました。
skip-character-set-client-handshake <–これのおかげです。
どうもありがとうございました。
skip-character-set-client-handshake
分かりやすい説明で非常に助かりました。