MDB2_Driver_mysqlは1.5.0系を使うべき
PHPからSET NAMES〜のクエリでMySQLの文字コードを変更するのは危険で、文字エンコーディング設定は必ずAPIから行う(例えば、mysql_set_charset()を使う)べきだといわれています。
SET NAMESは禁止 – yohgaki's blog
ところで、PEARのMDB_Driver_mysqlではデータベースへの接続時に指定するDSN(データソース名)の中で文字コードを指定できるようになっています。
では、文字コードを指定した場合、MDB_Driver_mysqlは上記のページで推奨されているようにmysql_set_charset()を使って文字コードを変更しているのでしょうか?それとも、危険と言われている「SET NAMES〜」を使っているのでしょうか?
バージョン1.4.1のソースコードを見てみましょう。
<?php /* MDB2/Driver/mysql.php 507〜517行目 */ function setCharset($charset, $connection = null) { if (is_null($connection)) { $connection = $this->getConnection(); if (PEAR::isError($connection)) { return $connection; } } $query = "SET NAMES '".mysql_real_escape_string($charset, $connection)."'"; return $this->_doQuery($query, true, $connection); } ?>
DSNに文字コードが指定されたときにsetCharsetメソッドを呼び出しています。
バージョン1.4.1ではSET NAMES 〜のクエリを実行しています。上で紹介した記事の内容に照らすと、これは安全ではないということになります。
それでは、バージョン1.5.0b2ではどうでしょうか。
<?php /* MDB2/Driver/mysql.php 613〜640行目 */ function setCharset($charset, $connection = null) { if (is_null($connection)) { $connection = $this->getConnection(); if (PEAR::isError($connection)) { return $connection; } } $collation = null; if (is_array($charset) && 2 == count($charset)) { $collation = array_pop($charset); $charset = array_pop($charset); } $client_info = mysql_get_client_info(); if (function_exists('mysql_set_charset') && version_compare($client_info, '5.0.6')) { if (!$result = mysql_set_charset($charset, $connection)) { $err =& $this->raiseError(null, null, null, 'Could not set client character set', __FUNCTION__); return $err; } return $result; } $query = "SET NAMES '".mysql_real_escape_string($charset, $connection)."'"; if (!is_null($collation)) { $query .= " COLLATE '".mysqli_real_escape_string($connection, $collation)."'"; } return $this->_doQuery($query, true, $connection); } ?>
バージョン1.5.0b2ではmysql_set_charset()が使えるかどうかを調べ、使用可能な場合にはmysql_set_charset()を呼び出すようになってます。
よって、1.5.0系を使うほうが安全だといえるでしょう。