I have problems inserting values with special Characters in names like "Renè". The Name "Renè" shows up in my Database like this: "René"
I tried to change the field in the database to "utf8_general_ci" which didn't help, so its probably something in my code.
The name comes from a JQuery Ajax Request and I am able to echo this name inside the called .php file correctly.
$fullname = $_POST['playersearch'];
echo "<div class='n_ok'><p>Inserted $fullname successfully (PlayerID is $id)</p></div>";
I connect to my DB using PDO and I specified the UTF-8 charset:
$db = new PDO("mysql:host=$dbhost;dbname=$dbname",$dbuser,$dbpass,array('charset'=>'utf8'));
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
The insert into the DB happens here:
$stmt = $db->prepare("INSERT INTO PlayerCards (playerName, buyPercentage) VALUES (?, ?)");
$stmt->bindParam(1, $fullname);
$stmt->bindParam(2, $buypercentage);
Why does it look so weird in my MySQL Database?
As per the manual:
http://php.net/manual/en/ref.pdo-mysql.connection.php
It specifies that the character set syntax in PDO be used as:
$options = array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
);
Also read the warning on that page:
Warning
The method in the below example can only be used with character sets that share the same lower 7 bit representation as ASCII, such as ISO-8859-1 and UTF-8. Users using character sets that have different representations (such as UTF-16 or Big5) must use the charset option provided in PHP 5.3.6 and later versions.
Therefore and in your case, by changing
array('charset'=>'utf8')
to
array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")
if you wish to run an initialisation command after connecting; more on this in comments below.
As stated by Phil in comments; there is no need to run an initialisation command after connecting.
Using mysql:host=$dbhost;dbname=$dbname;charset=utf8 can also be used.
The 4th argument (options array) is for specific driver options (usually PDO attributes) set on the connection.
Thank you Phil.
Related
I'm in a situation where I need to update some rows in a table named "matrículas'. The query looks something like this:
UPDATE `matrículas` SET...
When I run this query in my SQL program (HeidiSQL) directly, it executes without problems. When I do it in PHP via a PDO object, I get the following error:
SQLSTATE[HY000]: General error: 1300 Invalid utf8 character string: 'matr\xEDculas'
My PDO object is set up like this:
$db= new PDO(
'mysql:host='.$credentials['host'].';dbname='.$credentials['dbname'].';charset=utf8',
$credentials['user'],
$credentials['password'],
array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")
);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
The actual update is done by taking the above query and doing this:
$query = $this->db->prepare($sql);
$query->execute($params);
Both the table and the database were created using the utf8_general_ci collation.
Any ideas what I'm doing wrong? btw, I'm currently testing in Windows in case that has anything to do with it...
ERROR 1300 (HY000): Invalid utf8 character string: 'matr\xEDculas'
The \xNN notation gives the hex encoded value for the invalid byte(s) in the character string.
Unicode code point 237 (í), when encoded in utf-8, is a 2-byte character that is encoded as 0xC3 0xAD... but the error shows 0xED, which happens to be the ISO/IEC-8859-1 (Latin1) encoding for the character í.
Since the error is related to a column name being passed from the script rather than external data, that suggested what turned out to be the issue -- that the PHP script, itself, had the column name encoded incorrectly, since the character set in which the script had been saved was ISO-8859-1 rather than UTF-8.
`matrículas`
this is cp866-gp2312 encoding
please change it to utf-8 like matriculas
i having the different encoding style
If you must use accented letters in table names, then they must be encoded in UTF-8 in the client.
That is, it is not a PDO problem, but an encoding problem is your source editor/language/whatever.
I have São Tomé and Príncipe stored in a MySQL database.
It displays on my web page as S�o Tom� and Pr�ncipe
Is there anyway to display it properly straight from the database?
My MySQL Type is MyISAM and the collation is utf8_general_ci
My web page charset is <meta charset="utf-8">
Field type is set to varchar(30) and field collations is same as table utf8_general_ci
PHP FUNCTION TESTS
utf8_decode() converted characters to S?o Tom? and Pr?ncipe
htmlspecialchars_decode() converted characters to S�o Tom� and Pr�ncipe
html_entity_decode() converted characters to S�o Tom� and Pr�ncipe
quoted_printable_decode() converted characters to S�o Tom� and Pr�ncipe
htmlentities() returned blank result
GOT IT TO WORK THANKS TO #SAEVEN
Ran this right before my query SELECT
mysqli_query($GLOBALS['db_link'], "SET NAMES 'utf8'");
Could it be that you need to specify your namespace collation at the connection level?
I assume that you've covered the basics, you've got the charset as utf8 in your HTML markup.
Try executing this SQL statement before you do any of your database queries:
'SET NAMES utf8'
e.g., if you are using PDO
// do your regular connection logic whatever it is
$dbc = new PDO( .... );
$dbc->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$dbc->query( 'SET NAMES utf8' );
// run your queries beneath
....
or can use the shorthand
new PDO(
'mysql:host=mysql.example.com;dbname=awesome_db',
"username",
"password",
array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8")
);
Whatever DBAL you use, that query'll work. Just run it on the same connection you use to pull your data, before pulling it (only needs to be done once)
I'm fetching data in Arabic from MySQL tables with MySQLi. So I usually use this in procedural style:
mysql_query("SET NAMES 'utf8'");
mysql_query('SET CHARACTER SET utf8');
Now I am using the OOP style so I am trying to see if there is something I could set rather than the above?
I only found this in PHP manual so I did it, but what about setting names to UTF8?
$mysqli->set_charset("utf8");
It's the same:
$mysqli->query("SET NAMES 'utf8'");
From the manual:
This is the preferred way to change the charset. Using mysqli::query()
to execute SET NAMES .. is not recommended.
$mysqli->set_charset("utf8"); is just enough, let the mysqli db driver do the thing for you.
You should use
$mysqli->set_charset("utf8");
Don't use SET NAMES or SET CHARACTER SET explicitly when using MySQLi., and certainly don't use both like the question asker here originally was. Reasons that this is a bad idea:
Calling SET CHARACTER SET utf8 after SET NAMES utf8 actually just undoes some of the work that SET NAMES did.
The PHP manual explicitly warns us to use mysqli_set_charset, not SET NAMES:
This is the preferred way to change the charset. Using mysqli_query() to set it (such as SET NAMES utf8) is not recommended. See the MySQL character set concepts section for more information.
Under the hood, mysqli_set_charset is just a wrapper for mysql_set_character_set from the MySQL C API (or its mysqlnd equivalent). Looking at the docs for that function, we can see the difference between it and SET NAMES:
This function works like the SET NAMES statement, but also sets the value of mysql->charset, and thus affects the character set used by mysql_real_escape_string()
In other words, $mysqli->set_charset('foo') will do everything SET NAMES foo does and also ensure that mysqli_real_escape_string respects the new encoding. Admittedly, if you're only using encodings like Latin 1 and UTF 8 that strictly extend ASCII (that is, which encode all ASCII strings exactly as they would be encoded in ASCII), then using SET NAMES instead of set_charset won't break anything. However, if you're using more unusual encodings like GBK, then you could end up garbling your strings or even introducing SQL injection vulnerabilities that bypass mysqli_real_escape_string.
It's thus good practice to only use set_charset, not SET NAMES. There's nothing that SET NAMES does that set_charset doesn't, and set_charset avoids the risk of mysqli_real_escape_string behaving incorrectly (or even insecurely).
You can use this. Its realy nice for mysqli Character Set
$dbhost = "localhost";
$dbuser = "root";
$dbpass = "dbpass";
$dbname = "dbname";
$conn = mysqli_connect($dbhost,$dbuser,$dbpass,$dbname);
mysqli_query($conn,"SET CHARACTER SET 'utf8'");
mysqli_query($conn,"SET SESSION collation_connection ='utf8_unicode_ci'");
For procedural style lovers.
// Create connection
$conn = mysqli_connect($servername, $username, $password, $dbname);
/* change character set to utf8 */
mysqli_set_charset($conn,"utf8");
mysqli_query($conn,"SET NAMES 'latin5'");
$conn = connection string
what's up? :-)
I have one problem and i hope you can help me with it.
One friend of mine have a simple solid html website and i implemented little php; CRUD system for articles... problem i came across is placing and getting cyrillic characters from mysql database.
What i want to achive is next:
In the main navigation there are some separated sections, whose names, ids and item's order i want to place in mysql and than to pull names and to put each name as a link. Names are supposed to be cyrillic characters.
The problem comes when i, using php mysql_fetch_assoc function, try to display names which are inserted with cyrillic characters in database row, collation of row is utf8_general_ci, and i end with ????? insted of original characters. If i submit cyrillic characters via submit form to mysql it shows something like this У.
How can i solve this, thanks in advance!? :-)
Make sure you call this after connecting to database.
mysql_query("SET NAMES UTF8");
Also make sure that HTML file has charset meta tag set to UTF-8 or send header before output.
header("Content-Type: text/html; charset=utf-8");
I had the same problem until I encoded the 'Collation' column in my table to 'utf8_bin'.
if its really mysql fetch assoc messing up you should try:
mysql-set-charset
from the docs:
Note:
This is the preferred way to change
the charset. Using mysql_query() to
execute SET NAMES .. is not
recommended.
also make sure your files are saved as utf8 and check iconv_set_encoding / iconv_get_encoding
For anyone having more complex issues with legacy project upgrades from versions before PHP 5.6 and MYSQL 5.1 to PHP 7 & Latest MySQL/Percona/MariaDB etc...
If the project uses utf8_encode($value) you can either try removing the function from the value being prepared and use the accepted answer for setting UTF-8 encoding for all input.
--- OR ---
Try replacing utf8_encode($value) with mb_convert_encoding($value, 'utf-8')
PDO USERS
If you are using PDO here are two ways how to set utf8:
$options = [
\PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'
];
new \PDO($dsn, $username, $passwd, $options);
--- OR ---
$dsn = 'mysql:host=localhost;charset=utf8;'
new \PDO($dsn, $username, $passwd);
I can confirm that mb_convert_encoding($value, 'utf-8') to SQL table using utf8_unicode_ci works for Cyrillic and Umlaut.
I've a MySQL table that has a UTF-8 charset and upon attempting to insert to it via a PHP form, the database gives the following error:
PDOStatement::execute():
SQLSTATE[HY000]: General error: 1366
Incorrect string value: '\xE8' for
column ...
The character in question is 'è', yet I don't see why this should be a problem considering the database and table are set to UTF-8.
Edit
I've tried directly from the mysql terminal and have the same problem.
Your database might be set to UTF-8, but the database connection also needs to be set to UTF-8. You should do that with a SET NAMES utf8 statement. You can use the driver_options in PDO to have it execute that as soon as you connect:
$handle = new PDO("mysql:host=localhost;dbname=dbname",
'username', 'password',
array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
Have a look at the following two links for more detailed information about making sure your entire site uses UTF-8 appropriately:
UTF-8 all the way through…
UTF8, PHP and MySQL
E8 is greater than the maximum usable character 7F in a one-byte UTF8 character: http://en.wikipedia.org/wiki/UTF-8
It seems your connection is not set to UTF8 but some other 8 bit encoding like ISO Latin. If you set the database to UTF8 you only change the character set the database uses internally, connections may be on a different default value (latin1 for older MySQL versions) so you should try to send an initial SET CHARACTER SET utf-8 after connecting to the database. If you have access to my.cnf you can also set the correct default value there, but keep in mind that changing the default may break any other sites/apps running on the same host.
Before passing the value to Mysql you can use the following code:
$val = mb_check_encoding($val, 'UTF-8') ? $val : utf8_encode($val);
convert the string the to UTF-8, If it's matter of only one field.