Joan Joan - 1 year ago 165
PHP Question

PDO connection : UTF-8 declaration with SET NAMES / CHARACTER SET?

According to, StackOverflow and other sources of trust, I can find 4 different ways to set UTF-8 on PDO connection, but can't find wich one is the better to choose.

A PDO connection code (and some inits) :

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

$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(
$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());

So, what I understood, is that the Method 1 only work with PHP 5.3+ (but it seems that it's a bit buggy), and method 2 is for MySQL only.
Differences between method 3 and 4 is MySQL thing, but I still don't know wich one is better. And is there a way to call SET NAMES in PDO attributes, but not for MySQL only?


Answer Source

Setting it in DSN is the only proper way (although it is only supported since 5.3).
You can this one and SET NAMES at the same time.

All the other ways will make infamous half-fictional GBK injection possible.

Please note that your setting for error_reporting() is utterly wrong. it have to be unconditional -1. If you concerned about displaying errors - there is a proper ini setting for this, called display_errors, can be set at runtime.
While error_reporting sets level of the error and should be at max all the time.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download