Home > DB > PHPとMySQLの個人的まとめ

PHPとMySQLの個人的まとめ

3月 17th, 2006
Goto comments Leave a comment

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の文字コードとなる。

cockok DB

  1. | #1

    始めまして。

    MySql の文字化けにハマってこちらのページに流れ着きました。
    skip-character-set-client-handshake
    の一行に救われました。

    ありがとうございました。。

  2. cockok
    | #2

    初めまして、コメントありがとうございます。
    私もかなり悩んでいた所だったので、お役に立って何よりです。

  3. mysql
    | #3

    同じ現象が起きた際にphp.iniに以下を追加したら直りました。
    mysql.default_charset = UTF-8

    追記したらapache reboot

  4. cockok
    | #4

    知らないオプションだったので調べてみましたが、標準のオプションではありませんでした。
    パッチ(見つかりませんでしたが)を当ててコンパイルすれば、そちらのオプションを追加でいけるようになるかもしれませんが、php.net等からバイナリを取得する場合はオプションがなく、php側では制御できませんので、MySQL側の設定が必要になるかと思います。

  5. nobody
    | #5

    通りすがりです。
    すごい助かりました、、わかりやすく書いてあって。
    ありがとうございます!!

  6. koby
    | #6

    書かれてから1年以上たった今日、この問題をこのページで解決出来た私。
    本当にありがとうござます。

  7. | #7

    始めまして。

    > MySQL4.1以降はサーバとは別にクライアントの文字コードが設定されている。

    この一言で、問題がなんなのか分からない状態から抜け出すことができました。
    本当にありがとう!

  8. | #8

    はじめまして。
    ずーっと悩んでましたが、おかげで解決しました。
    本当にありがとうございました。
    skip-character-set-client-handshake が魔法に感じました。

  9. | #9

    どうも、初めまして。
    他の方も書かれていますが、まさにskip-character-set-client-handshakeに救われました。
    著名なブログ(と書いては失礼かも知れませんが)では一切書かれていないので、もうお手上げ状態でした。
    本当に、本当に助かりました。

  10. | #10

    はじめまして。助かりました?

  11. ee
    | #11

    半月ほど悩んでいたのですが「skip-character-set-client-handshake」のお陰で解決できました。
    本当にありがとうございます。
    助かりました。

  12. saku
    | #12

    みなさんと同じく、
    skip-character-set-client-handshake
    に救われました。ありがとうございました。

  13. fa
    | #13

    はじめまして

    ここのページのおかげで、非常に助かりました!!
    昨日、この問題にぶつかり、解決策が見つからないまま
    行き詰っていました。
    このブログを見つけたおかげで、終電で帰ることができました。
    今後もこちらのブログを参考にさせて頂くつもりです。

    ありがとうございました!

  14. 通りすがり
    | #14

    はじめまして。

    今さらですが、文字化けをこのページのおかげで直すことができました。
    skip-character-set-client-handshake <–これのおかげです。
    どうもありがとうございました。

  15. js
    | #15

    skip-character-set-client-handshake
    分かりやすい説明で非常に助かりました。

  1. | #1
  2. | #2
  3. | #3
  4. | #4
  5. | #5
  6. | #6
  7. | #7