MySQLとPDOの組み合わせでcharsetを指定する を見て思いたしたこと。
PHP 5.3.6より前のバージョンの PDO MySQL で charset を指定するには次のようにする。
<?php
$options = array(
PDO::MYSQL_ATTR_READ_DEFAULT_FILE => '/etc/my.cnf',
);
$pdo = new PDO(
'mysql:host=yourhost;dbname=yourdb',
'user', 'password', $options
);
/etc/my.cnf
[client]
default-character-set = utf8
この方法ならPDOの中の libmysql に charset を知らせることが出来る。SET NAMES
だとMySQLサーバには charset が伝わるけれどクライアント側は latin1 のままなのでエスケープ処理で問題が出る可能性があります(と、思ったけれどプリペアドステートメントなら大丈夫?)。
なお、この方法は PDO の中が libmysql でなければ使えません。Linux 版のビルドでは大抵大丈夫だと思いますが、Windows 版のビルドでは PDO の中身が mysqlnd なのでこの方法は使えません(PDO::MYSQL_ATTR_READ_DEFAULT_FILE
というクラス定数が存在しない)。
追記
APサーバとDBサーバが別の場合などは my.cnf で connect-timeout も指定しておくと良いかもしれません。DBサーバが死んだ時にデフォルトだと相当長いタイムアウト時間になっていたと思うので。
ただ、その場合に
[client]
default-character-set = utf8
connect-timeout = 1
などとしてしまうと mysqldump などのコマンドが使えなくなってしまうので、次のように php 用のセクションを作ります。
<?php
$options = array(
PDO::MYSQL_ATTR_READ_DEFAULT_FILE => '/etc/my.cnf',
PDO::MYSQL_ATTR_READ_DEFAULT_GROUP => 'php',
);
$pdo = new PDO(
'mysql:host=yourhost;dbname=yourdb',
'user', 'password', $options
);
/etc/my.cnf
[client]
default-character-set = utf8
[php]
default-character-set = utf8
connect-timeout = 1