PDOでMySQLに接続するとエラー発生

環境

事象

コード

事象を再現させるための実験コード。
といっても、普通にPDO接続するだけ。

<?php
define('DSN','mysql:host=localhost;dbname=hoge');
define('DB_USER','hoge');
define('DB_PASSWORD','hoge');

try {
  $dbh =  new PDO(DSN, DB_USER, DB_PASSWORD, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
} catch (PDOException $e) {
  echo $e->getMessage();
  exit;
}
結果
SQLSTATE[HY000] [2000] mysqlnd cannot connect to MySQL 4.1+ using the old insecure authentication. Please use an administration tool to reset your password with the command SET PASSWORD = PASSWORD('your_existing_password'). This will store a new, and more secure, hash value in mysql.user. If this user is used in other scripts executed by PHP 5.2 or earlier you might need to remove the old-passwords flag from your my.cnf file

原因

PHP5.3からの下位互換のない変更点に該当しているため。

新しい mysqlnd ライブラリは、MySQL 4.1 用の41バイトの新しいパスワードフォーマットを使用します。 古い16バイトのパスワードを使うと、mysql_connect() 系の関数は次のようなエラーメッセージを生成します。"mysqlnd cannot connect to MySQL 4.1+ using old authentication"

http://php.net/manual/ja/migration53.incompatible.php

要するにMySQLのパスワード設定が古いからのようだ。

対応

管理者ユーザでパスワードを再設定してやればOK。

SET SESSION old_passwords=0;
SELECT * FROM user WHERE user = 'hoge';
UPDATE user SET password = password('XXXXXXXXXXXX') WHERE user = 'hoge';