PDO连接:使用SET NAMES / CHARACTER SET的UTF-8声明?

时间:2012-12-26 15:16:06

标签: php pdo database-connection

根据php.net,StackOverflow和其他信任来源,我可以找到4种不同的方式在PDO连接上设置UTF-8,但找不到哪一种更好选择。

PDO连接代码(以及一些内容):

$localhost = $_SERVER['SERVER_NAME'] == 'localhost';
error_reporting(-1); ini_set('display_errors', $localhost); // Old : error_reporting($localhost ? -1 : 0); see answer above
date_default_timezone_set('Europe/Paris');

$pdo_db = 'mysql:host=localhost;dbname=local_db;charset=utf8'; // METHOD #1
$pdo_login = 'root';
$pdo_pass = 'localpass';

try {
    $db = new PDO($pdo_db, $pdo_login, $pdo_pass, array(
        PDO::ATTR_ERRMODE => $localhost ? PDO::ERRMODE_EXCEPTION : PDO::ERRMODE_SILENT,
        PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8', // METHOD #2
    ));
    $db -> exec('SET NAMES utf8'); // METHOD #3
    $db -> exec('SET CHARACTER SET utf8'); // METHOD #4
    $db -> exec('SET time_zone = \''.date_default_timezone_get().'\'');
} catch (PDOException $error) {
    die($error -> getMessage());
}

所以,我理解的是,方法1仅适用于PHP 5.3+(但似乎它有点错误),而方法2仅适用于MySQL。 方法3和方法4之间的差异是MySQL thing,但我仍然不知道哪个更好。有没有办法在PDO属性中调用SET NAMES,但不能仅用于MySQL?

谢谢!

2 个答案:

答案 0 :(得分:6)

在DSN中设置它是唯一正确方式(尽管自5.3以来仅支持)。
你可以同时使用这个和SET NAMES

所有其他方式都可能使臭名昭着的半虚构GBK注射成为可能。

请注意,您对error_reporting()的设置完全错误。它必须是无条件的-1。 如果您担心显示错误 - 可以在运行时设置适当的ini设置,称为display_errors。 虽然error_reporting设置错误的级别,但应始终保持最大值。

答案 1 :(得分:-2)

我总是在我的dbconfig文件中写下这些代码:

mysql_query("SET character_set_results = 'utf8',
                 character_set_client = 'utf8', 
                 character_set_connection = 'utf8',
                 character_set_database = 'utf8',  
                 character_set_server = 'utf8'");