Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PDO + MySQL and broken UTF-8 encoding

I use the PDO library with a MySQL database in PHP, but if I insert any data encoded in UTF-8, like Arabic words, it’s inserted into the database, but as ?????????.

In my own framework, after I create the PDO connection, I send two queries – SET NAMES utf8 and SET CHARACTER SET utf8. It still doesn’t work.

Example:

loadclass('PDO', array(     sprintf(         'mysql:host=%s;port=%s;dbname=%s',         confitem('database', 'host'),         confitem('database', 'port'),         confitem('database', 'name')     ),     confitem('database', 'username'),     confitem('database', 'password'),     array('PDO::ATTR_PERSISTENT' => confitem('database', 'pconnect')) )); $this->query('SET NAMES ' . confitem('database', 'charset')); $this->query('SET CHARACTER SET ' . confitem('database', 'charset')); 

Workaround: Use the json_encode function to convert data before inserting it to the database, and use json_decode to decode it after fetching. This is how I do it now.

like image 901
Jason4Ever Avatar asked Dec 17 '10 23:12

Jason4Ever


People also ask

Does MySQL support UTF-8?

MySQL supports multiple Unicode character sets: utf8mb4 : A UTF-8 encoding of the Unicode character set using one to four bytes per character. utf8mb3 : A UTF-8 encoding of the Unicode character set using one to three bytes per character.

Can I use PDO with MySQL?

Unlike MySQLi, PDO is only object-oriented and supports a number of different database types that use PHP, such as MySQL, MSSQL, Informix, and PostgreSQL.

How do I change MySQL encoding to UTF-8?

To change the character set encoding to UTF-8 for the database itself, type the following command at the mysql> prompt. Replace dbname with the database name: Copy ALTER DATABASE dbname CHARACTER SET utf8 COLLATE utf8_general_ci; To exit the mysql program, type \q at the mysql> prompt.

What is the difference between utf8mb4 and UTF-8 charsets in MySQL?

utf-8 can store only 1, 2 or 3 bytes characters, while utf8mb4 can store 4 bytes characters as well. utf-8 is a subset of characters given by utf8mb4 .


2 Answers

Warning: This answer applies to PHP 5.3.5 and lower. Do not use it for PHP version 5.3.6 (released in March 2011) or later.

Compare with Palec's answer here.


Use:

$pdo = new PDO(      'mysql:host=hostname;dbname=defaultDbName',      'username',      'password',      array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")  );  

It forces UTF-8 on the PDO connection. It worked for me.

like image 62
shark555 Avatar answered Sep 23 '22 12:09

shark555


You have to set the correct character set for the connection. Add the charset=utf8 option to the DSN (this is MySQL-specific!)

$pdo = new PDO(     'mysql:host=hostname;dbname=defaultDbName;charset=utf8',     'username',     'password' ); 

However, in PHP versions before 5.3.6 (released in March 2011), you must use a workaround as the charset option in the DSN is not supported.

$pdo = new PDO(     'mysql:host=hostname;dbname=defaultDbName',     'username',     'password',     array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8") ); 
like image 44
Palec Avatar answered Sep 20 '22 12:09

Palec