月: 2012年2月

PDOでmysqlに接続する時の文字コード

久しぶりにメモ。

開発環境でPDOからmysqlにつないでデータを入れたりしてたのに
本番サーバに設置した途端にプログラムから入れたデータが文字化けした。

mysql> show variables like 'character_set%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       | 
| character_set_connection | utf8                       | 
| character_set_database   | utf8                       | 
| character_set_filesystem | binary                     | 
| character_set_results    | utf8                       | 
| character_set_server     | utf8                       | 
| character_set_system     | utf8                       | 
| character_sets_dir       | /usr/share/mysql/charsets/ | 
+--------------------------+----------------------------+
8 rows in set (0.01 sec)

dbにつないで文字コードの設定をみてみたけど問題なかったので変だなーと。

で、以下のプログラムで確認。

$PDO=NULL;
try {
    $PDO=new PDO(
        sprintf('mysql:host=%s;dbname=%s','localhost','dbname'),'user','password',
        array(
            PDO::MYSQL_ATTR_READ_DEFAULT_FILE=>'/etc/my.cnf',
            PDO::MYSQL_ATTR_READ_DEFAULT_GROUP=>'client',
            PDO::ATTR_EMULATE_PREPARES=>'FALSE'));
    $PDO->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);
} catch(PDOException $e) {
    var_dump($e->getMessage());
}

//$PDO->query("SET NAMES utf8");


$sth=$PDO->prepare("SHOW VARIABLES LIKE 'char%'");
$sth->execute();
while($ins=$sth->fetchObject()){
    echo $ins->Variable_name . " | " . $ins->Value . "\n";
}

開発環境での結果…

$ php connect_test.php
character_set_client | utf8
character_set_connection | utf8
character_set_database | utf8
character_set_filesystem | binary
character_set_results | utf8
character_set_server | utf8
character_set_system | utf8
character_sets_dir | /usr/share/mysql/charsets/

本番環境の結果…

$ php connect_test.php
character_set_client | latin1
character_set_connection | latin1
character_set_database | utf8
character_set_filesystem | binary
character_set_results | latin1
character_set_server | utf8
character_set_system | utf8

コレですね…

どうも開発環境では/etc/my.cnfに[client]に文字コードの
指定があったから上手くいってたけど、本番環境では
/etc/my.cnfに文字コードの設定がちゃんとされていないのが問題
だったみたい。

今回の本番環境は/etc/my.cnfを勝手に触れないので

$PDO->query("SET NAMES utf8");

で対応する。。

いろんな環境で動かすならSET NAMESはちゃんと書いておいたほうが良さそうですね。