PHP PDO: charset, set names? - php

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

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");

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");
?>

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.

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 with PDO::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).

$conn = new PDO("mysql:host=$host;dbname=$db;charset=utf8", $user, $pass);

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

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');
}

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

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'];
}

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

Related

PDO Postgresql UTF8 charset

I'm looking for a way to connect to the postgresql database using UTF8 charset.
Currently, I have to send a query request after the connexion to specify the charset. It is not optimal at all...
$connect = new \PDO("pgsql:host=$this->host;dbname=$this->base", $this->user, $this->pass);
$connect->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
$connect->query("SET NAMES '$this->charset'");
MySQL allows to pass a table on argument to specify the charset, I'm looking for the same thing.
$this->db = new \PDO("pgsql:host=$this->PARAM_hote;dbname=$this->PARAM_nom_bd", $this->PARAM_utilisateur, $this->PARAM_mot_passe, array(\PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''));
$this->db->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
Went with :
new PDO('pgsql:host=' . $db_host . ';dbname=' . $db_name . ';options=\'--client_encoding=UTF8\'', $db_username, $db_password, array(PDO::ATTR_PERSISTENT => true));
As a matter of fact, the single quote to pass the option --client_encoding=UTF8 is very important and a double one doesn't works.
You can pass 'options' key like this:
$dbh = new PDO
(
"pgsql:dbname=mydbname;host=myhost;port=5432;options='--client_encoding=UTF8'",
"username",
"password"
);
Try add params in constructor:
$connect = new \PDO("pgsql:host=$this->host;dbname=" . $this->base . ";options='-c client_encoding=utf8'", $this->user, $this->pass);
$connect->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);

How to Set Character Set in PDO

i've some issue with setting character set in pdo. Below is my connection code :-
private function Connect()
{
$this->settings = parse_ini_file("settings.ini.php");
//$dsn = 'mysql:dbname='.$this->settings["dbname"].';host='.$this->settings["host"].'';
$dsn = 'mysql:dbname=' . $this->settings["dbname"] . ';host=' . $this->settings["host"] .';charset=utf8'. ';connect_timeout=15';
try
{
# Read settings from INI file, set UTF8
$this->pdo = new PDO($dsn, $this->settings["user"], $this->settings["password"], array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
# We can now log any exceptions on Fatal error.
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
# Disable emulation of prepared statements, use REAL prepared statements instead.
$this->pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
# Connection succeeded, set the boolean to true.
$this->bConnected = true;
}
catch (PDOException $e)
{
# Write into log
echo $this->ExceptionLog($e->getMessage());
die();
}
}
I am inserting french character as céréales but it is storing as céréales in DB. Anyone know how to set character set to utf8 in pdo?
You are already setting the utf8 charset in the connection string. You don't have to send another query like "SET NAMES 'uft8'".
You just have to make sure that:
Mysql table and field are utf8 (like uft8_general_ci)
Input data is utf-8
The array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8") is also useless. This is the faster way to set all your parameters:
$this->pdo = new PDO('mysql:host='.$this->settings["host"].';dbname='.$this->settings["dbname"].';
charset=utf8;connect_timeout=15', $this->settings["user"], $this->settings["password"],
array(PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));

Encoding PHP MySQL

I can see query results but I also see � character with some characters like "Á".
Basic connection is like this:
$mysqli = new mysqli(server, user, pass, db);
mysqli_set_charset($mysqli, 'utf8');
I also tried with:
$mysqli->query("SET NAMES 'utf8'");
$mysqli->set_charset("utf8");
mysql_query("SET NAMES 'utf8'");
But characters are still watching.
Query
function connection($mysqli) {
mysql_query("SET NAMES 'utf8'");
if ( ! $link = mysqli_connect("localhost", "user", "pass") ) {
echo ("Error");
return false;
}
if ( ! mysqli_select_db($link, "db") ) {
echo ("Error");
return false;
}
if ( ! $consulta = mysqli_query($link, $mysqli) ) {
echo ("Error");
return false;
}
return $consulta;
}
All files are saved with UTF8, VAR columns in DB are with UTT8 too.
What or where is the problem?
Thank you!
Maybe your php file is saved as an ANSI doc, try with UTF8 without BOM.
Also try to declare the charset UTF8 on your output file.
Hope it help

PHP PDO Keep Getting Error: Charset=UTF8 : An invalid keyword charset was specified in the dsn string

I keep getting this error : PHP PDO : Charset=UTF8 : An invalid keyword charset was specified in the dsn string.
My code is like this
function ConnectToSQLAndGetDBConnSTRVar() {
try {
$dbname = "irina";
$serverName = ".\SQLEXPRESS";
$username = "USERNAME";
$pw = "PASSWORD";
$dbh = new PDO ("sqlsrv:server=$serverName;Database=$dbname;charset=utf8","$username","$pw");
return $dbh;
}
catch (PDOException $e) {
print "Failed to get DB handle: " . $e->getMessage() . "\n";
exit;
}
}
And it doesnt matter how I write utf8.. UTF8 or UTF-8 or utf-8 none of them work for me..
So what do i do please help me..
You can find the parameters accepted in the DSN string on this page of the PHP manual.
There is no Charset parameter in DSNs for the "SQL Server" PDO driver (with the DSN prefix sqlserv:).
Bear in mind that all PDO drivers have different DSN conventions, as they are passed directly to the driver and not normalised by PDO.
There is an alternative PDO driver for SQL Server called "PDO_DBLIB", which does take charset as a DSN parameter, but it has the prefix "sybase:", "mssql:", or "dblib:", depending on compilation options.
I had same error while following the instructions from here to prevent sql injections
reading manual - it is said that prior to php 5.3.6 charset was ignored, and you can use it including options:
$dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname;
// Set options
$options = array(
PDO::ATTR_PERSISTENT => true,//can help to improve performance
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, //throws exceptions whenever a db error occurs
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES uft8' //>= PHP 5.3.6
);
try {
$this->conn = new PDO($dsn, $this->user, $this->pass, $options);
}
catch ( PDOException $e ) {
$this->error = $e->getMessage();
}

PDO UTF-8 encoding issue?

i am using PDO for connecting to MYSQL database
all tables in database have utf8_unicode_ci Collation
here is my connection code :
<?php
$mysql_username = "root";
$mysql_password = "";
$mysql_host = "localhost";
$mysql_database = "cms";
try
{
//connect
global $db;
$db = new PDO('mysql:dbname=' . $mysql_database . ';host=' . $mysql_host . ';charset=utf8;', $mysql_username, $mysql_password);
$db->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, 'SET NAMES utf8');
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $ex)
{
die("Unable Connect To DataBase");
}
?>
in localhost i have no problem with encoding but when i uploaded the source to a host i see ?????? instead of characters?
This:
$db->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, 'SET NAMES utf8');
is entirely pointless. See http://php.net/manual/en/ref.pdo-mysql.php. The MYSQL_ATTR_INIT_COMMAND is executed right after the connection is established, no later. If you set this on an already fully created PDO object, it's too late and it never executes. You need to pass it to the constructor:
new PDO(..., ..., ..., array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'))
Alternatively, if your PHP version supports it, add charset=utf8 to the DSN.

Categories