PHP PDO: charset, set names?
PhpMysqlPdoPhp Problem Overview
I had this previously in my normal mysql_* connection:
mysql_set_charset("utf8",$link);
mysql_query("SET NAMES 'UTF8'");
Do I need it for the PDO? And where should I have it?
$connect = new PDO("mysql:host=$host;dbname=$db", $user, $pass, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
Php Solutions
Solution 1 - Php
You'll have it in your connection string like:
"mysql:host=$host;dbname=$db;charset=utf8mb4"
HOWEVER, prior to PHP 5.3.6, the charset option was ignored. If you're running an older version of PHP, you must do it like this:
$dbh = new PDO("mysql:host=$host;dbname=$db", $user, $password);
$dbh->exec("set names utf8mb4");
Solution 2 - Php
Prior to PHP 5.3.6, the charset option was ignored. If you're running an older version of PHP, you must do it like this:
<?php
$dbh = new PDO("mysql:$connstr", $user, $password);
$dbh -> exec("set names utf8");
?>
Solution 3 - Php
This is probably the most elegant way to do it.
Right in the PDO constructor call, but avoiding the buggy charset option (as mentioned above):
$connect = new PDO(
"mysql:host=$host;dbname=$db",
$user,
$pass,
array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"
)
);
Works great for me.
Solution 4 - Php
For completeness, there're actually three ways to set the encoding when connecting to MySQL from PDO and which ones are available depend on your PHP version. The order of preference would be:
charset
parameter in the DSN string- Run
SET NAMES utf8
withPDO::MYSQL_ATTR_INIT_COMMAND
connection option - Run
SET NAMES utf8
manually
This sample code implements all three:
<?php
define('DB_HOST', 'localhost');
define('DB_SCHEMA', 'test');
define('DB_USER', 'test');
define('DB_PASSWORD', 'test');
define('DB_ENCODING', 'utf8');
$dsn = 'mysql:host=' . DB_HOST . ';dbname=' . DB_SCHEMA;
$options = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
);
if( version_compare(PHP_VERSION, '5.3.6', '<') ){
if( defined('PDO::MYSQL_ATTR_INIT_COMMAND') ){
$options[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES ' . DB_ENCODING;
}
}else{
$dsn .= ';charset=' . DB_ENCODING;
}
$conn = @new PDO($dsn, DB_USER, DB_PASSWORD, $options);
if( version_compare(PHP_VERSION, '5.3.6', '<') && !defined('PDO::MYSQL_ATTR_INIT_COMMAND') ){
$sql = 'SET NAMES ' . DB_ENCODING;
$conn->exec($sql);
}
Doing all three is probably overkill (unless you're writing a class you plan to distribute or reuse).
Solution 5 - Php
I think you need an additionally query because the charset option in the DSN is actually ignored. see link posted in the comment of the other answer.
Looking at how Drupal 7 is doing it in http://api.drupal.org/api/drupal/includes--database--mysql--database.inc/function/DatabaseConnection_mysql%3A%3A__construct/7:
// Force MySQL to use the UTF-8 character set. Also set the collation, if a
// certain one has been set; otherwise, MySQL defaults to 'utf8_general_ci'
// for UTF-8.
if (!empty($connection_options['collation'])) {
$this->exec('SET NAMES utf8 COLLATE ' . $connection_options['collation']);
}
else {
$this->exec('SET NAMES utf8');
}
Solution 6 - Php
$con="";
$MODE="";
$dbhost = "localhost";
$dbuser = "root";
$dbpassword = "";
$database = "name";
$con = new PDO ( "mysql:host=$dbhost;dbname=$database", "$dbuser", "$dbpassword", array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
$con->setAttribute ( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
Solution 7 - Php
$conn = new PDO("mysql:host=$host;dbname=$db;charset=utf8", $user, $pass);
Solution 8 - Php
I just want to add that you have to make sure your database is created with COLLATE utf8_general_ci or whichever collation you want to use, Else you might end up with another one than intended.
In phpmyadmin you can see the collation by clicking your database and choose operations. If you try create tables with another collation than your database, your tables will end up with the database collation anyways.
So make sure the collation for your database is right before creating tables. Hope this saves someone a few hours lol
Solution 9 - Php
I test this code and
$db=new PDO('mysql:host=localhost;dbname=cwDB','root','',
array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
$sql="select * from products ";
$stmt=$db->prepare($sql);
$stmt->execute();
while($result=$stmt->fetch(PDO::FETCH_ASSOC)){
$id=$result['id'];
}
Solution 10 - Php
in my case, i had to add this line:
$conn->exec("set names utf8"); //Support utf8
How it will look:
$conn = new PDO("mysql:host=$servername;dbname=$db", $username, $password);
$conn->exec("set names utf8"); //Support utf8